我正在用C语言编写一个方法,其中有一个文件的单词列表,该文件是从标准输入重定向的。但是,当我尝试将单词读入数组时,我的代码将仅输出第一个字符。我了解这是因为char和char *的转换问题。
虽然我在挑战自己不要使用string.h中的任何函数,但我尝试进行迭代并考虑编写自己的strcpy函数,但由于输入来自我自己的文件而感到困惑从标准输入重定向。变量numwords
由用户在main方法(未显示)中输入。
我正在尝试通过dumpwptrs
调试此问题,以告诉我输出是什么。我不确定代码中的内容是什么导致我得到错误的输出-是通过字读取块数组的方式还是用wptrs错误地指向它?
//A huge chunk of memory that stores the null-terminated words contiguously
char chunk[MEMSIZE];
//Points to words that reside inside of chunk
char *wptrs[MAX_WORDS];
/** Total number of words in the dictionary */
int numwords;
.
.
.
void readwords()
{
//Read in words and store them in chunk array
for (int i = 0; i < numwords; i++) {
//When you use scanf with '%s', it will read until it hits
//a whitespace
scanf("%s", &chunk[i]);
//Each entry in wptrs array should point to the next word
//stored in chunk
wptrs[i] = &chunk[i]; //Assign address of entry
}
}
答案 0 :(得分:2)
请勿重复使用先前词中的char chunk[MEMSIZE];
。
请使用下一个未使用的内存。
char chunk[MEMSIZE];
char *pool = chunk; // location of unassigned memory pool
// scanf("%s", &chunk[i]);
// wptrs[i] = &chunk[i];
scanf("%s", pool);
wptrs[i] = pool;
pool += strlen(pool) + 1; // Beginning of next unassigned memory
严格的代码将检查scanf()
的返回值,并确保i, chunk
不超过限制。
只要每次输入 word 行,我都会寻求fgets()
解决方案。
char chunk[MEMSIZE];
char *pool = chunk;
// return word count
int readwords2() {
int word_count;
// limit words to MAX_WORDS
for (word_count = 0; word_count < MAX_WORDS; word_count++) {
intptr_t remaining = &chunk[MEMSIZE] - pool;
if (remaining < 2) {
break; // out of useful pool memory
}
if (fgets(pool, remaining, stdin) == NULL) {
break; // end-of-file/error
}
pool[strcspn(pool, "\n")] = '\0'; // lop off potential \n
wptrs[word_count] = pool;
pool += strlen(pool) + 1;
}
return word_count;
}
答案 1 :(得分:0)
尽管我在挑战自己不要使用string.h中的任何功能,...
不使用string.h
中的任何功能来挑战自己的最佳方法是自己编写然后使用它们。
您的程序读取缓冲区i
的{{1}}-esim位置中的下一个单词,因此您将获得每个单词的第一个字母(只要chunk
不每次阅读都超过i
的大小时,您用刚读过的单词覆盖了最后一个单词的第二个字符和其余字符。然后,将所有指针放在chunk
中以指向这些位置,从而无法将一个字符串的末尾与下一个字符串区分开(您覆盖了所有空终止符,仅保留了最后一个),因此您将获得第一个字符串,包含单词中所有单词的首字母,但最后一个字母完整。那么第二个将具有相同的字符串,但是从第二个开始……然后是第三个……等等。
构建您自己的wptrs
版本,并使用strdup(3)
临时存储字符串...然后使用您的chunk
版本动态创建该字符串的副本,并创建指针指向它...。等等。
最后,当您完成操作后,只需释放所有分配的字符串并voilà!!
这也非常重要:请阅读How to create a Minimal, Complete, and Verifiable example,因为您的代码经常缺少一些已从已发布的代码中消除的错误(您通常不知道错误在哪里,或者您会更正它,在这里没有问题吧?)