我有一个与字符串和指针有关的问题。 请仅用C / C ++程序解释....
有一个文件,每行包含1个单词。 我知道没有。文件中的单词。请在小代码的帮助下解释,如何有效地将这些单词存储在RAM中。
fscanf(fp,"%s",word) & strcpy
是将单词存储在RAM中的唯一方法......没有其他有效的算法或逻辑可用..
感谢。
答案 0 :(得分:3)
执行此操作的最有效方法可能是在一个块中将整个文件读入内存(使用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';
}
}
这是使用strtok
的稍微简单的版本:
char* buffer;
char** words;
void readfile(FILE *file, int len, int wordcnt)
{
buffer = (char*) malloc(sizeof(char) * len);
fread(buffer, 1, size, file);
buffer[len] = '\0';
words = (char**) malloc(sizeof(char*) * wordcnt);
int curword = 0;
char* ptr = strtok(buffer, "\n");
while (ptr != NULL)
{
words[curword++] = ptr;
ptr = strtok(NULL, "\n");
}
}
请注意,以上两个示例假定文件中的最后一个单词以换行符结束!
答案 1 :(得分:1)
您可以将整个文件读入内存块,然后遍历该块,用0替换每个'\ r'或'\ n'。现在您可以通过搜索块来恢复所有字符串紧跟一个或多个0的字符。这就像你将获得的空间效率一样。现在,如果您还想要快速访问,则可以分配另一个指针块,并将每个指针设置为指向字符串的开头。比指针块更有效,每个指针指向一个单独分配的String。
答案 2 :(得分:0)
如果您希望字符串不消耗额外的未使用字节,请执行以下操作:
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);
答案 3 :(得分:0)
为什么strcpy
?只需fscanf直接进入目标内存。
答案 4 :(得分:0)
因为,引用 - “请仅使用C / C ++程序解释....”使用包含字符串的向量很容易 - std::vector< std::string >
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();
}
所有阅读的单词都会复制到向量readWords
中,您可以遍历它以查看它们实际上是什么。
答案 5 :(得分:0)
这是一种快速而肮脏的方法,没有错误检查,使用静态内存和使用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]);
}