我想弄清楚如何从一个给定的位置开始从数组中获取字符串。假设我们有一个任意长的数组,并且我的字符串从1000开始。如果我想从文件中获取字符串,我只需使用getc或scanf之类的东西。我如何在数组而不是文件上执行这些相同的功能?从数组捕获字符串
*哦,请记住,该数组的类型为int,并且充满了ASCII字符的数字表示形式。
我想弄清楚如何从一个给定的位置开始从数组中获取字符串。假设我们有一个任意长的数组,并且我的字符串从1000开始。如果我想从文件中获取字符串,我只需使用getc或scanf之类的东西。我如何在数组而不是文件上执行这些相同的功能?从数组捕获字符串
*哦,请记住,该数组的类型为int,并且充满了ASCII字符的数字表示形式。
假设字符串为null结束的元素(不指定你怎么知道的字符串的结尾),那么一点点LINQ的应该做的伎俩:
var chars = ints.Skip(1000).TakeWhile(i => i != 0).Select(i => (char)i);
var str = new string(chars.ToArray());
第一像跳过1000个整数,需要他们,而他们不是空终止,然后将它们转换成字符作为适合表示ASCII码整数。第二行简单地将它们变成一个字符串。
如果字符串没有空终止符,并且刚刚在数组结束时结束,那么只需删除对TakeWhile
的调用。
如果你用byte[]
处理数组,那么你可能只是这样做:
string yourString = Encoding.ASCII.GetString(yourArray, startIndex, length);
因为你的阵列是int[]
类型,那么的 - 假设每个元素代表一个ASCII字符 - 你会需要首先将这些int
s转换为byte
。如果数组是“任意长”,那么你可能不希望整个事情转换为byte[]
阵列,在这种情况下,只是转换您需要的部分:
byte[] temp =
yourArray.Skip(startIndex).Take(length).Select(i => (byte)i).ToArray();
string yourString = Encoding.ASCII.GetString(temp);
如果您int[]
阵列中的每个元素没有按” t实际上代表一个ASCII字符,那么你需要给我们更多关于它使用的精确格式的信息。
这只适用于数组类型为byte []的情况。提问者指定数组的类型为int []。 – 2010-06-11 16:13:09
@Joseph:这个应该可以工作,因为select会收到一个'IEnumerable
@John Saunders:我的评论是在LukeH编辑他的答案之前做出的。正如你所指出的,他的第二个解决方案在int []上工作。 – 2010-06-12 03:28:45
你能切从阵列和呼叫ASCIIEncoding.GetString()就可以了
LINQ有时可以是相当的手...
var ints = Enumerable.Range(0, 255).ToArray();
var start = 65;
var length = 26;
var value = new string(ints.Select(i => (char)i)
.Skip(start)
.Take(length)
.ToArray());
Console.WriteLine(value); //ABCDEFGHIJKLMNOPQRSTUVWXYZ
这里是一个替代(类似于solution provided by LukeH),可能会更快(因为它使用内置的阵列方法,而不是LINQ):
public static string GetString(int[] array, int startIndex, int length)
{
var subarray = new int[length];
Array.Copy(array, startIndex, subarray, 0, length);
return Encoding.ASCII.GetString(Array.ConvertAll(subarray, i => (byte)i));
}
这是我的代码仅供参考。如果你转到“SYSCALL”部分,你会发现有关“open 4”的if语句,这是我卡住的地方。哦,顺便说一下,我没有使用visual studio,我正在使用一个名为“Verilator”的程序,它允许我将Verilog代码与C++代码进行交互。
#include "VMIPS.h"
#include "VMIPS_MIPS.h"//required to explicitly access signals from submodules
#include <verilated.h>
#include <cstdio>
#include <cmath>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <vector>
using namespace std;
unsigned int main_time = 0;
static inline int hexCharValue(char ch)
{
if (ch>='0' && ch<='9')return ch-'0';
if (ch>='a' && ch<='f')return ch-'a'+10;
return 0;
}
int main(int argc, char **argv)
{
///////////////////////////////////////// Instruction Capture /////////////////////////////////////////////
ifstream inClientFile("TEXT.txt",ios::in); //stream object
//test if instruction file can be opened
if (!inClientFile)
{
cerr << "File couldn't be opened" << endl;
return 1; //no point using exit inside main
}
//fill string array with all file values and determines length of program
vector<string> words;
words.reserve(274815);
string word;
while (inClientFile >> word)words.push_back(word); //helper function is unnecessary
cout << "Number of words:" << words.size() << endl;
const int wordCount=words.size();
vector<int> InstructionMemory;
vector<string> tempInstructionMemory;
tempInstructionMemory.reserve(wordCount);
//cut out undesired strings from vector
for(int i=0; i<wordCount; i++)
{
if (words[i].length()==8 && words[i].find("fs24")==string::npos) //f0 can exist at pos 1 in a valid hex string
{
tempInstructionMemory.push_back(words[i]);
}
}
//convert string hex to numerical decimal
InstructionMemory.resize(tempInstructionMemory.size());
for(int j=0; j<tempInstructionMemory.size(); j++)
{
for(int y=0; y<8; y++)
{
InstructionMemory[j]+=hexCharValue(tempInstructionMemory[j][y])<<(4*(7-y));//4194608+4*
}
}
//printf("Amortized Instruction Vector Size:%d\n",InstructionMemory.size());
////////////////////////////////////// Data Capture ////////////////////////////////////////////////
ifstream inClientDataFile("DATA.txt",ios::in); //stream object
//test if instruction file can be opened
if (!inClientDataFile)
{
cerr << "File couldn't be opened" << endl;
return 1; //no point using exit inside main
}
//fill string array with all file values and determines length of program
vector<string> datas;
datas.reserve(274815);
string data;
while (inClientDataFile >> data)datas.push_back(data); //helper function is unnecessary
cout << "Number of data packets:" << datas.size() << endl;
const int dataCount=datas.size();
vector<int> DataMemory;
vector<string> tempDataMemory;
tempDataMemory.reserve(dataCount);
//cut out undesired strings from vector
for(int i=0; i<dataCount; i++)
{
if (datas[i].length()==8 && datas[i].find("fs24")==string::npos) //f0 can exist at pos 1 in a valid hex string
{
tempDataMemory.push_back(datas[i]);
}
}
//convert string hex to numerical decimal
DataMemory.resize(tempDataMemory.size());
for(int j=0; j<tempDataMemory.size(); j++)
{
for(int y=0; y<8; y++)
{
DataMemory[j]+=hexCharValue(tempDataMemory[j][y])<<(4*(7-y));
}
}
//printf("Amortized Data Vector Size:%d\n",DataMemory.size());
/////////////////////////////////////////// MIPS I processor interface /////////////////////////////////////////////
Verilated::commandArgs(argc, argv);
VMIPS *top = new VMIPS;
top->CLK = 0;
vector<int> HS0,HS1,HS2;
vector<string> FDT_filename;
vector<int> FDT_state;//1 = open, 0 = closed
int FileDescriptorIndex = 3;//start of non-reserved indecies
FILE *f;
//first 3 positions reserved for stdin, stdout, and stderr
FDT_filename.push_back("stdin");
FDT_filename.push_back("stdout");
FDT_filename.push_back("stderr");
FDT_state.push_back(0);
FDT_state.push_back(0);
FDT_state.push_back(0);
//int FDT[100];
printf("IMAddr:%d IM:%d \n***************\n",top->Iaddr,InstructionMemory[(top->Iaddr)/4]);
while (!Verilated::gotFinish())
{
//clock generation
top->CLK=!(top->CLK);
//vector mapping
if ((top->Daddr >= 0) && (top->Daddr <= 419604))
{
if(top->MemRead)
top->Din = HS0[(top->Daddr)/4];
if(top->MemWrite)
HS0[(top->Daddr)/4] = top->Dout;
}
else if ((top->Daddr >= (419608+InstructionMemory.size()+4)) && (top->Daddr <= 268435452))
{
if(top->MemRead)
top->Din = HS1[(top->Daddr-419608)/4];
if(top->MemWrite)
HS1[(top->Daddr-419608)/4] = top->Dout;
}
else if ((top->Daddr >= 268435456) && (top->Daddr <= (268435456+DataMemory.size())))
{
if(top->MemRead)
top->Din = DataMemory[(top->Daddr-2668435456)/4];
if(top->MemWrite)
DataMemory[(top->Daddr-2668435456)/4] = top->Dout;
}
else if (top->Daddr >=(268435456+DataMemory.size()+4))
{
if(top->MemRead)
top->Din = HS2[(top->Daddr-(268435456+DataMemory.size()+4))/4];
if(top->MemWrite)
HS2[(top->Daddr-(268435456+DataMemory.size()+4))/4] = top->Dout;
}
//instruction supply mapping
if (top->Iaddr < 4194608)
{
top->Iin = InstructionMemory[(top->Iaddr)/4];
}
else
{
top->Iin = InstructionMemory[(top->Iaddr-4194608)/4];
}
//instruction split
if(main_time%2)
printf("IMAddr:%d IM:%d \n***************\n",top->Iaddr,InstructionMemory[(top->Iaddr)/4]);//-4194608)/4]);
//evaluate instruction call and increment time counter
top->eval();
main_time++;
//exit loop
if(main_time>=2)
{
return 0;
}
top->Iin = 3690987776;
//SYSCALL
if (top->Iin == 3690987584)//exit 1
{
cout << "Exit" << endl;
return 0;
}
else if (top->Iin == 3690987776)//open 4
{
cout << endl << endl << "Open File" << endl << endl;
string filename;
filename = "DATA.txt";
//fill filename with characters from memory
//FDT_filename(top->a0) is the string start pointer
FDT_filename.push_back(filename);//add new filename to newest location
FDT_state.push_back(1);//add new open indicator to newest location
top->v0 = FileDescriptorIndex;//place file descriptor into register
FileDescriptorIndex++;//ready the next file descriptor
//printf("Filename:%d FileDescriptorIndex:%d",FDT_filename.at3(FileDescriptorIndex),FileDescriptorIndex);
}
else if (top->Iin == 3690987648)//read 2
{
cout << "Read" << endl;
int max_char_count = top->a2;
int char_CTR = 0;
//create file object and open filename
//read chars from file
//place in
//FILE *f = fopen(filename,"rb");
//scanf("%s %top->a2",&FDT_filename(top->a0) >> top->a1;
//top->v0 = char_CTR;
}
else if (top->Iin == 3690987712)//write 3
{
cout << "Write" << endl;
int max_char_count = top->a2;
int char_CTR = 0;
//f fopen(FDT_filename(top->a0));
}
else if (top->Iin == 3690987840)//close 5
{
cout << "Close File" << endl;
//FDT_state(top->v0)=0;
}
else if (top->Iin == 3690987904)//time 6
{
cout << "Time:" << main_time << endl;
top->a0 = main_time;
top->a1 = main_time;
}
}
}
是否需要包含一些文件以便使用var和byte?对不起,我是新手。 – 2010-06-11 17:31:24
请不要在标题中包含标签(C#)。将它们留在标签中。另外,请张贴一些代码,如果您收到编译错误,请显示错误并说出您正在使用的Visual Studio版本。 – 2010-06-11 17:43:57
当我使用Greg的想法时, var chars = DataMemory.Skip(top-> a0).TakeWhile(i => i!= 0).Select(i =>(char)i); var str = new string(chars.ToArray()); 我收到错误,说var尚未声明。 – 2010-06-11 18:15:08