将 stdin 的输入读取到指针数组中,直到 EOF,但没有任何输出?[已结束]

Reading input from stdin into an array of pointers until EOF, but nothing comes out as output? [closed]

提问人:Pomegranate Society 提问时间:6/26/2019 更新时间:6/26/2019 访问量:357

问:


这个问题是由一个错别字或一个无法再重现的问题引起的。虽然类似的问题可能在这里成为主题,但这个问题的解决方式不太可能帮助未来的读者。

4年前关闭。

我正在尝试编写一个程序,其中有一个整数,称为 ,它指定从文件中读取的字数。但是,我正在针对一个字数少于用户输入的文件对其进行测试。例如,我有输入numwords

this

should

not 

work

其中 5 基于用户输入。我想用退出代码 1 终止程序,所以我写了以下代码来帮助我:numwords

当我使用具有适当数量的单词作为用户输入的文件时,似乎不会打印出输出(程序具有用于打印值的其他功能)。在我将 while 语句添加到代码之前,正在打印输出。我觉得我的 scan 语句在 while 循环中有问题。在我添加到 while 循环之前,我只使用了 for 循环和注释掉的 ,我的程序工作正常 - 输入被读入,并使用了适当的输出。然而,我只是试图实现一个条件,在这种情况下,上述情况的字数少于失败的字数。numwordswptrsscanf("%s", unused)numwords

//A huge chunk of memory that stores the null-terminated words contiguously
char chunk[MEMSIZE];

//Location of unused memory
char *unused = chunk;

//Points to words that reside inside of chunk
char *wptrs[MAX_WORDS];

/** Total number of words in the dictionary */
int numwords;

void readwords()
{
  int i = 0;
  while ((scanf("%s", unused)) != EOF) {
    for (i = 0; i < numwords; i++) {
      //Read in words and store them in chunk array
      //scanf("%s", unused);
      wptrs[i] = unused;
      unused += mystrlen(wptrs[i]) + 1;
    }
  }

  //Check to see if fewer input than specified
  if (numwords > i) {
    printf("%d", i);
    exit(EXIT_NUM_WORDS_BAD);
  }
}

我希望这种情况以退出代码 1 退出程序,但我发现它以代码 0 退出,因为 main 方法只有 .有没有办法以代码 1 退出,并在有适当数量的等效字数时使我的程序正常工作?先谢谢你。return 0numwords

C 数组 scanf stdin eof

评论

0赞 Neil 6/26/2019
你到底在做什么?循环的目的是什么?有什么问题?forn = scanf("%s %s %s %s %s", ...)
0赞 Pomegranate Society 6/26/2019
@NeilEdelman 对于这个程序,我依赖于用户输入。用户输入决定了我应该期望多少输入,如果我的输入少于指定的输入,我应该退出程序。我觉得以这种方式设置可能不起作用?n
1赞 Antti Haapala -- Слава Україні 6/26/2019
你的问题是你的(默认)初始化为零,你永远不会改变它的值。你期望这里发生什么!?或。。。如果不是,那么 for 循环总是迭代 from 0 以在到达 时中断循环,因此它永远不会少。numwordsinumwordsnumwords
0赞 Neil 6/27/2019
用户计算输入数量似乎是计算机可以轻松、更准确地完成的问题,例如,通过读取文件两次,或者,如果它是在线处理的,则分配越来越大的容量块并进行计数。

答:

1赞 gdea73 6/26/2019 #1

修改后的示例:如果满足单词配额或读取 EOF,则中断循环。while

我任意选择了 5(更确切地说,在原始代码中)。读取五行输入后,将打印结果。不需要显式 EOF。如果在 5 个单词之前满足 EOF,则打印错误,我们退出并返回代码 1。words_expectednumwords

根据您的评论,我添加了一个检查,用于检查给定的行是否仅包含数字。如果是这样,程序将停止处理输入。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MEMSIZE 1024
#define MAX_WORDS 5

//A huge chunk of memory that stores the null-terminated words contiguously
char chunk[MEMSIZE];

//Location of unused memory
char *unused = chunk;

//Points to words that reside inside of chunk
char *wptrs[MAX_WORDS];

/** Total number of words in the dictionary */
int words_expected = 5;

int contains_only_digits(char *s)
{
    int i = 0;
    for (i = 0; i < strlen(s); i++) {
        if (!isdigit(s[i])) {
            return 0;
        }
    }

    return 1;
}

void readwords()
{
    int words_read = 0;
    while (words_read < words_expected && scanf("%s", unused) != EOF) {
        // Read in words and store them in chunk array
        wptrs[words_read] = unused;
        if (contains_only_digits(wptrs[words_read])) {
            break;
        }
        unused += strlen(wptrs[words_read]) + 1;
        words_read++;
    }

    //Check to see if fewer input than specified
    if (words_read < words_expected) {
        printf("Expected %d words, but %d were provided\n", words_expected,
                words_read);
        exit(1);
    }
}

void printwords()
{
    int i = 0;
    for (i = 0; i < words_expected; i++) {
        printf("word %d: %s\n", i + 1, wptrs[i]); 
    }
}

int main(int argc, char **argv)
{
    readwords();
    printwords();
}

该函数是一个朴素的实现。明智的做法是使用并检查您是否对确定 C 字符串是否为数字的最佳实践感兴趣。contains_only_digitsstrtolerrno

评论

0赞 Pomegranate Society 6/26/2019
我之前实际上也尝试过这个,但它对一个有 6 个和 6 个单词的文件失败了。这就是我最初使用 for 循环的原因。我认为使用您列出的方法,具有正确数量的匹配单词的输入可能仍然失败 bc 从 0 开始递增?numwordsnumwordsi
0赞 gdea73 6/26/2019
是否期望每行输入一个单词?如果是这样,只要提供 5 个或更多单词,我发布的测试程序就会以 0 退出。 初始化为 0,但它应该准确表示使用 读取的单词数。iscanf
0赞 Pomegranate Society 6/26/2019
我认为关于我正在阅读的文件的另一个重要方面(我肯定忘记提及)是,适当的文件也有后面的整数,不应该被读取。有没有办法施加一个条件,如果读取一个整数,那么程序应该停止读取输入?
0赞 gdea73 6/26/2019
我已经更新了我的回复,以便在读取预期的字数后停止,并打印结果。希望这适用于您的用例。如果您发现任何其他问题,请告诉我。编辑(刚刚看到您的最新评论):是的,您可以在 while 循环中检查每个字符。如果你发现“单词”以这种方式只包含数字,那么你可以打破这个循环。isdigit()wptrs[words_read]
1赞 Pomegranate Society 6/26/2019
您的解决方案非常完美。我感激不尽!