【问题标题】:Array replacing elements that i dont want数组替换我不想要的元素
【发布时间】:2020-10-17 18:32:29
【问题描述】:

我想把每个单词都放在一个数组中。

这是代码。

这是输出

据我所知,每次我有一个新行时,数组的第一个单词都会被文件下一行的第一个单词替换,但我不明白为什么。 我在这里没有显示,但是在新行之后,所有其他位置都是错误的。

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define MAX_LINE_LEN 256

void usage (const char *prog) {
    fprintf (stderr, "Usage (words): %s [file_path]\n", prog);
    exit (1);
}

void split_print_words (const char *filename) {
    FILE *fd = stdin;  // By default will read from stdin
    if (filename != NULL && strcmp (filename, "-") != 0) {
        // A file name was given, let's open it to read from there
        fd = fopen (filename, "r");
        assert (fd != NULL);
    }

    char buffer[MAX_LINE_LEN];
    
    while(fgets(buffer, sizeof(buffer), fd != NULL)) {
        char *token;
        token = strtok(buffer, " \n");
        while(token!=NULL) {
            write(1, token, strlen(token));
            write(1, "\n", 1);
            token = strtok(NULL, " \n");
        }
    }
}

int main (int argc, char *argv[]) {
    // Check there is one and only one argument
    if (argc < 1 || argc > 2) {
        usage (argv[0]);
    }

    split_print_words (argv[1]);

    exit (0);
}

【问题讨论】:

  • 请将代码和输入/输出示例包含为文本,而不是模糊图像。
  • 有输入输出和代码的照片,我看得很清楚
  • 但是我们不想要照片,我们想要可以复制和粘贴的文本。见:minimal reproducible example
  • 为什么你的 strtok 分隔符是“\t\n”?如果要将句子拆分为单词,则分隔符应该只是一个空格:“”。此外,看起来您每次都在打印 words[0],而不是 words[nwords]。
  • fd == NULL 作为第三个参数传递给fgets 是一个错误。这将 [可能] 评估为 0(即NULL)。您希望第三个参数 [简单地] 是:fd。你想要:while(fgets(buffer, sizeof(buffer), fd) != NULL) {

标签: c file strtok


【解决方案1】:

试试这个(阅读 cmets):

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

#define MAX_LINE_LEN 256
#define WORDS_N 10

int main(void)
{
    FILE* fp;

    // Open the file and check if it was opened
    fp = fopen("myfile.txt", "r");
    if (fp == NULL) {
      perror("Failed: ");
      return 1;
    }

    // Temporary buffer that will store one line of the file at a time
    char buffer[MAX_LINE_LEN];
    // NULL-initialized 2D array of size 'WORDS_N' x 'MAX_LINE_LEN'
    char words[WORDS_N][MAX_LINE_LEN] = {0};
    // Count how many words we actually read from the file
    int count = 0;
    // To be used by 'strtok()'
    char* pch;
    // Read file line by line
    while (fgets(buffer, MAX_LINE_LEN, fp))
    {
        // Remove trailing newline
        buffer[strcspn(buffer, "\n")] = 0;
        //printf("%s\n", buffer);

        // Split line by whitespace
        pch = strtok(buffer, " ");
        // For each token in the split line
        while (pch != NULL)
        {
          // If the array has available space
          if(count < WORDS_N)
            // Put the current token into the array
            strcpy(words[count++], pch);
          //printf ("%s\n", pch);

          // Proceed to next token
          pch = strtok(NULL, " ");
        }
    }

    // Print array
    for (int i = 0; i < count; ++i)
        printf("%s\n", words[i]);

    // Close file
    fclose(fp);
    return 0;
}

输入(myfile.txt):

This is a
test and is
not working!

输出:

This
is
a
test
and
is
not
working!

【讨论】:

    【解决方案2】:

    正如 cmets 中指出的,你应该替换这个:

    while(fgets(buffer, sizeof(buffer), fd != NULL)) {
    

    用这个:

    while((fgets(buffer, sizeof(buffer), fd)) != NULL) {
    

    我不确定您是如何设置编译器的。当我编译你的代码时,我显然收到了来自 gcc 的警告:

    arrayreplace.c: In function ‘split_print_words’:
    arrayreplace.c:27:48: warning: passing argument 3 of ‘fgets’ makes pointer from integer without a cast [-Wint-conversion]
       27 |         while(fgets(buffer, sizeof(buffer), fd != NULL)) {
          |                                                ^
          |                                                |
          |                                                int
    In file included from arrayreplace.c:3:
    /usr/include/stdio.h:564:69: note: expected ‘FILE * restrict’ but argument is of type ‘int’
      564 | extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
          |                                                    ~~~~~~~~~~~~~~~~~^~~~~~~~
    

    进行此更改后,我能够看到从文件中解析的所有单词:

    src : $ cat wordsarr.txt 
    This ia a
    test and is
    not working
    src : $ ./a.out wordsarr.txt 
    This
    ia
    a
    test
    and
    is
    not
    working
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-19
      • 1970-01-01
      • 2018-11-06
      • 2017-04-28
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      相关资源
      最近更新 更多