【问题标题】:Why are there extra characters in the output of the following C code?为什么以下 C 代码的输出中有多余的字符?
【发布时间】:2022-01-10 03:49:57
【问题描述】:

我有文件 statistics.txt 以下数据在哪里:

Mark = 100
Andy = 200

然后,我写了这段代码:

FILE *file_statistics_reading = fopen("statistics.txt", "r");

char line[1024];
int n = 0;
char player[10];

while (fgets(line, sizeof(line), file_statistics_reading) != NULL) {
    n = 0;
    for (int i = 0; i < 10; i++) {
        if ((line[i] > 'A') && (line[i] < 'z')) {
            player[n] = line[i];
            n = n + 1;
        }
    }
    printf("%s", player);
}

fclose(file_statistics_reading);

我想从文本文件中提取球员的名字并打印出来,但是输出是这样的:

Mark╠╠╠╠╠╠╠╠╠╠╠╠╠
Andy╠╠╠╠╠╠╠╠╠╠╠╠╠

有什么解决办法吗?

【问题讨论】:

  • 您需要 NUL 终止数组以使其成为有效字符串。 player[n] = '\0';printf 之前。当然你也应该增加player 的大小,以确保它总是能适应NUL。
  • @kaylum 谢谢!
  • C 中的字符串不仅仅是字符数组,它们是以空字符结尾的字符数组。当您让编译器通过在源代码中提及它来为您构造一个字符串时,它会为您附加空字符。当您让大多数 C 函数为您创建字符串时(例如 fgetsscanf%s),它们会为您添加空字符。但是,当您自己构建一个字符串时,一次一个字符,就像您在这里所做的那样,您有责任自己添加空字符。

标签: arrays c string io char


【解决方案1】:

代码中存在多个问题:

  • 您忘记在player 中的名称后设置空终止符,这解释了输出中的随机字节。 player 是一个自动数组:其内容在创建时是不确定的。
  • 您应该将player 增加一个字节。
  • 字母测试不正确:'A''z' 将导致循环停止,因为您使用 &gt;&lt; 而不是 &gt;=&lt;=
  • 根据字符集,将打印一些非字母字节,例如[\]^_` 用于ASCII。您应该使用 &lt;ctype.h&gt; 中的 isalpha()
  • 如果行中出现多个单词,则前 10 个字节中的字母作为所有行的单个 blob。用换行符分隔输出。
  • 您不检查行尾,因此即使读取超出行尾的内容也会测试 10 个字节,其内容不确定。

这是修改后的版本:

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

void print_players(void) {
    char line[1024];
    FILE *file_statistics_reading = fopen("statistics.txt", "r");
    
    if (file_statistics_reading == NULL) {
        perror("cannot open statistics.txt");
        return;
    }
    while (fgets(line, sizeof(line), file_statistics_reading) != NULL) {
        char player[11];
        size_t n = 0;
        for (size_t i = 0; n < sizeof(player) - 1 && line[i] != '\0'; i++) {
            if (isalpha((unsigned char)line[i]) {
                player[n++] = line[i];
            }
        }
        player[n] = '\0';
        printf("%s\n", player);
    }
    fclose(file_statistics_reading);
}

这是另一种打印行中第一个单词的方法:

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

void print_players(void) {
    char line[1024];
    FILE *file_statistics_reading = fopen("statistics.txt", "r");
    const char *letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    if (file_statistics_reading == NULL) {
        perror("cannot open statistics.txt");
        return;
    }
    while (fgets(line, sizeof(line), file_statistics_reading) != NULL) {
        int start = strcspn(line, letters);       // skip non letters
        int len = strspn(line + start, letters);  // count letters in word
        printf("%.*s\n", len, line + start);
    }
    fclose(file_statistics_reading);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    • 2020-02-14
    • 2019-05-05
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多