C 弦乐;指针

C 弦乐;指针,c,algorithm,data-structures,C,Algorithm,Data Structures,我有一个关于字符串和指针的问题。 请仅使用C/C++程序进行解释 有一个文件,每行包含一个单词。 我知道档案里有多少字。请用小代码解释一下,我如何能有效地将这些单词存储在RAM中 fscanf(fp,“%s”,word)和strcpy是将单词存储在RAM中的唯一方法吗。。。没有其他有效的算法或逻辑可用 谢谢。如果您希望字符串不消耗额外的未使用字节,请执行以下操作: char * * array=new char*[COUNT_OF_WORDS]; fscanf(fp,"%s",word);

我有一个关于字符串和指针的问题。 请仅使用C/C++程序进行解释

有一个文件,每行包含一个单词。 我知道档案里有多少字。请用小代码解释一下,我如何能有效地将这些单词存储在RAM中

fscanf(fp,“%s”,word)和strcpy
是将单词存储在RAM中的唯一方法吗。。。没有其他有效的算法或逻辑可用


谢谢。

如果您希望字符串不消耗额外的未使用字节,请执行以下操作:

char * * array=new char*[COUNT_OF_WORDS];


fscanf(fp,"%s",word);
int len=strlen(word);
array[i]=new char[len+1];
strcpy(array[i],word);

如果希望字符串不消耗额外的未使用字节,请执行以下操作:

char * * array=new char*[COUNT_OF_WORDS];


fscanf(fp,"%s",word);
int len=strlen(word);
array[i]=new char[len+1];
strcpy(array[i],word);

可能最有效的方法是在一个块中将整个文件读入内存(使用
fread
)。然后分配一个指针数组,每个单词一个指针。然后遍历内存中的文件,将
\n
字符更改为
\0
,并将指针存储在数组中每个
\0
后面的字符中

它的效率很高,因为它只执行一个I/O操作、两次内存分配,并在文件中的字符上循环两次(一次将它们复制到缓冲区,另一次将它们拆分为单独的字符串)。您描述的算法(
fscanf
strcpy
)将执行许多I/O操作,为每个字分配内存,并在字符上循环至少三次(一次读取缓冲区,一次查找分配内存的长度,一次从缓冲区复制到分配的内存)

以下是一个没有错误检查的简单版本:

char* buffer; // pointer to memory that will store the file
char** words; // pointer to memory that will store the word pointers

// pass in FILE, length of file, and number of words
void readfile(FILE *file, int len, int wordcnt)
{
    // allocate memory for the whole file
    buffer = (char*) malloc(sizeof(char) * len);
    // read in the file as a single block
    fread(buffer, 1, size, file);

    // allocate memory for the word list
    words = (char**) malloc(sizeof(char*) * wordcnt);
    int found = 1, // flag indicating if we found a word
                   // (starts at 1 because the file begins with a word)
        curword = 0; // index of current word in the word list

    // create a pointer to the beginning of the buffer
    // and advance it until we hit the end of the buffer
    for (char* ptr = buffer; ptr < buffer + len; ptr++)
    {
        // if ptr points to the beginning of a word, add it to our list
        if (found)
            words[curword++] = ptr;
        // see if the current char in the buffer is a newline
        found = *ptr == '\n';
        // if we just found a newline, convert it to a NUL
        if (found)
            *ptr = '\0';
    }
}

请注意,以上两个示例假设文件中的最后一个单词以换行符结尾

最有效的方法可能是在一个块中将整个文件读入内存(使用
fread
)。然后分配一个指针数组,每个单词一个指针。然后遍历内存中的文件,将
\n
字符更改为
\0
,并将指针存储在数组中每个
\0
后面的字符中

它的效率很高,因为它只执行一个I/O操作、两次内存分配,并在文件中的字符上循环两次(一次将它们复制到缓冲区,另一次将它们拆分为单独的字符串)。您描述的算法(
fscanf
strcpy
)将执行许多I/O操作,为每个字分配内存,并在字符上循环至少三次(一次读取缓冲区,一次查找分配内存的长度,一次从缓冲区复制到分配的内存)

以下是一个没有错误检查的简单版本:

char* buffer; // pointer to memory that will store the file
char** words; // pointer to memory that will store the word pointers

// pass in FILE, length of file, and number of words
void readfile(FILE *file, int len, int wordcnt)
{
    // allocate memory for the whole file
    buffer = (char*) malloc(sizeof(char) * len);
    // read in the file as a single block
    fread(buffer, 1, size, file);

    // allocate memory for the word list
    words = (char**) malloc(sizeof(char*) * wordcnt);
    int found = 1, // flag indicating if we found a word
                   // (starts at 1 because the file begins with a word)
        curword = 0; // index of current word in the word list

    // create a pointer to the beginning of the buffer
    // and advance it until we hit the end of the buffer
    for (char* ptr = buffer; ptr < buffer + len; ptr++)
    {
        // if ptr points to the beginning of a word, add it to our list
        if (found)
            words[curword++] = ptr;
        // see if the current char in the buffer is a newline
        found = *ptr == '\n';
        // if we just found a newline, convert it to a NUL
        if (found)
            *ptr = '\0';
    }
}

请注意,以上两个示例假设文件中的最后一个单词以换行符结尾

您可以将整个文件读入内存块,然后遍历该块,用0替换每个'\r'或'\n'。现在,只需在块中搜索紧跟在一个或多个0之后的字符,即可恢复所有字符串。这是你将得到的最节省空间的。现在,如果您还希望快速访问,可以分配另一块指针,并将每个指针设置为指向字符串的开头。比一块指针(每个指针指向一个单独分配的字符串)更有效。

您可以将整个文件读入一块内存,然后遍历该块,用0替换每个'\r'或'\n'。现在,只需在块中搜索紧跟在一个或多个0之后的字符,即可恢复所有字符串。这是你将得到的最节省空间的。现在,如果您还希望快速访问,可以分配另一块指针,并将每个指针设置为指向字符串的开头。仍然比每个指针块都指向单独分配的字符串更有效。

为什么
strcpy
?只需将fscanf直接插入目标内存。

为什么
strcpy
?只需将fscanf直接插入目标内存。

因为,您引用了--“请仅使用C/C++程序进行解释…”使用包含字符串的向量很容易-
std::vector

std::string word;

std::vector < std::string > readWords ;  // A vector to hold the read words.

ifstream myfile ("fileToRead.txt");
if (myfile.is_open())
{
    while ( myfile.good() )
    {
       getline (myfile,word);  // This gets you the first word get copied to line.
       readWords.push_back(word) ; // Each read word is being copied to the vector
    }
    myfile.close();
}
std::字符串字;
std::vectorreadWords;//一个用来保存已读单词的向量。
ifstream myfile(“fileToRead.txt”);
如果(myfile.is_open())
{
while(myfile.good())
{
getline(myfile,word);//这将获取复制到第行的第一个单词。
readWords.push_back(word);//每个读取的单词都被复制到向量中
}
myfile.close();
}
所有读到的单词都被复制到向量
读单词中,您可以反复查看它们的实际内容。

因为您引用了--“请仅使用C/C++程序解释…”使用包含字符串的向量很容易-
std::vector

std::string word;

std::vector < std::string > readWords ;  // A vector to hold the read words.

ifstream myfile ("fileToRead.txt");
if (myfile.is_open())
{
    while ( myfile.good() )
    {
       getline (myfile,word);  // This gets you the first word get copied to line.
       readWords.push_back(word) ; // Each read word is being copied to the vector
    }
    myfile.close();
}
std::字符串字;
std::vectorreadWords;//一个用来保存已读单词的向量。
ifstream myfile(“fileToRead.txt”);
如果(myfile.is_open())
{
while(myfile.good())
{
getline(myfile,word);//这将获取复制到第行的第一个单词。
readWords.push_back(word);//每个读取的单词都被复制到向量中
}
myfile.close();
}

所有读取的单词都复制到向量
readWords
,您可以在其中进行迭代以查看它们的实际内容。

这里有一种快速而肮脏的方法,无需进行错误检查,使用静态mem和fgets

#define MAX_NUM_WORDS   10
#define MAX_LEN 128

void get_words(char *p_file, char *words)
{
  FILE *f;

  f = fopen(p_file, "r");
  while (fgets(words, MAX_LEN, f))
    words += MAX_LEN+1;

  fclose(f); 
}

main()
{
  char word_array[MAX_NUM_WORDS][MAX_LEN+1];
  int i;

  get_words("words.txt", word_array);

  for (i=0; i<MAX_NUM_WORDS; i++)
    printf("Word: %s", word_array[i]);
}
#定义最多10个单词
#定义最大长度128
void get_单词(char*p_文件,char*words)
{
文件*f;
f=fopen(p_文件,“r”);
while(fgets(words,MAX_LEN,f))
单词+=最大长度+1;
fclose(f);
}
main()
{
字符字数组[MAX_NUM_WORDS][MAX_LEN+1];
int i;
获取单词(“words.txt”,单词数组);

对于(i=0;i,这里有一种快速而肮脏的方法,无需错误检查,使用静态mem和fgets

#define MAX_NUM_WORDS   10
#define MAX_LEN 128

void get_words(char *p_file, char *words)
{
  FILE *f;

  f = fopen(p_file, "r");
  while (fgets(words, MAX_LEN, f))
    words += MAX_LEN+1;

  fclose(f); 
}

main()
{
  char word_array[MAX_NUM_WORDS][MAX_LEN+1];
  int i;

  get_words("words.txt", word_array);

  for (i=0; i<MAX_NUM_WORDS; i++)
    printf("Word: %s", word_array[i]);
}
#定义最多10个单词
#定义最大长度128
void get_单词(char*p_文件,char*wo