2010-06-11 4 views
1

Я пытаюсь выяснить, как получить строку из массива, начиная с определенной позиции. Скажем, у нас есть массив, который произвольно длинный, и моя строка начинается с местоположения 1000. Если бы я хотел получить строку из файла, я бы просто использовал что-то вроде getc или scanf или что-то в этом роде. Как выполнять эти же функции в массиве вместо файла?Capture String from Array

* oh, имейте в виду, что массив имеет тип int и полон числовых представлений символов ASCII.

+0

Есть ли какой-нибудь файл, который нужно включить, чтобы использовать var и byte? Извините, я новичок. –

+0

, пожалуйста, не включайте теги (C#) в заголовок. Оставьте их в тегах. Также, пожалуйста, разместите код, и если вы получаете ошибку компиляции, покажите ошибку и скажите, какую версию Visual Studio вы используете. –

+0

Когда я использую идею Грега, var chars = DataMemory.Skip (top-> a0) .TakeWhile (i => i! = 0). Выберите (i => (char) i); var str = новая строка (chars.ToArray()); Я получаю ошибки, говоря, что var не был объявлен. –

ответ

6

Предполагая, что строка оканчивается нулевым символом (вы не указываете, как вы знаете конец строки) то немного Linq должен сделать трюк:

var chars = ints.Skip(1000).TakeWhile(i => i != 0).Select(i => (char)i); 
var str = new string(chars.ToArray()); 

первом, как скачет 1000 Интс, принимает их, пока они не нуль-терминатор, а затем преобразует их в полукокса в качестве подходящей для Интс, представляющих ASCII коды. Вторая строка просто превращает их в строку.

Если строка не имеет нулевого терминатора и заканчивается только после окончания массива, просто удалите вызов TakeWhile.

9

Если вы имели дело с byte[] массивом, то вы можете просто сделать это:

string yourString = Encoding.ASCII.GetString(yourArray, startIndex, length); 

Поскольку ваш массив типа int[] затем - при условии, что каждый элемент представляет собой один ASCII символ - вы будете необходимо преобразовать их int s в byte s первый. Если массив «произвольно долго», то вы не можете преобразовать все это в byte[] массив, в этом случае просто преобразовать раздел, который вам нужно:

byte[] temp = 
    yourArray.Skip(startIndex).Take(length).Select(i => (byte)i).ToArray(); 
string yourString = Encoding.ASCII.GetString(temp); 

Если каждый элемент вашего int[] массива Безразлично» t фактически представляют собой один символ ASCII, тогда вам нужно будет предоставить нам больше информации о том, какой именно формат он использует.

+1

Это работает только в том случае, если массив имеет тип байта []. Ответчик указал, что массив имеет тип int []. –

+0

@Joseph: это должно работать, так как select получает 'IEnumerable ' и возвращает' IEnumerable ', который затем превращается в 'byte []'. –

+0

@John Saunders: Мой комментарий был сделан до того, как LukeH отредактировал его ответ. Его второе решение действительно работает на int [], как вы указали. –

0

Не могли бы вы отрезаете элементы из массива и вызова ASCIIEncoding.GetString() на нем

0

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 
1

Вот альтернативный (по аналогии с 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)); 
} 
0

Вот мой код для справки. Если вы перейдете в раздел «SYSCALL», вы найдете инструкцию if, относящуюся к «открытому 4», где я застрял. О, кстати, я не использую визуальную студию, я использую программу под названием «Verilator», которая позволяет мне связывать Verilog Code с кодом 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; 
     } 
    } 
}