Строка захвата из массива - PullRequest
1 голос
/ 11 июня 2010

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

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

Ответы [ 6 ]

9 голосов
/ 11 июня 2010

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

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

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

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

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

6 голосов
/ 11 июня 2010

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

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

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

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

1 голос
/ 11 июня 2010

Вот альтернатива (похожая на решение, предоставленное 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 голосов
/ 11 июня 2010

Вот мой код только для справки. Если вы зайдете в раздел «SYSCALL», вы найдете оператор if, относящийся к «open 4», вот где я застрял. Кстати, я не использую Visual Studio, я использую программу под названием «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;
        }
    }
}
0 голосов
/ 11 июня 2010

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
0 голосов
/ 11 июня 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...