为什么我的程序打印不可见的字符而不是字符串?

问题描述 投票:0回答:1

我需要用 C 语言编写一个程序,接收数字 N 和 N×单词(字符串)。找到具有最少字符数的单词,将所有其他单词减少到最小字符大小,然后按照给定的相反顺序打印它们。但打印后什么也没有出现。就像打印空格一样。

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

int main() {
  int N, min, i;
  char S[100][51], gra[51];

  scanf("%d", &N);

  if (N < 1 || N > 100) {
    printf("Wrong Input");

    return 1;
  }

  min = 52;

  for (i = 0; i < N; i++) {
    fgets(S[i], 51, stdin);

    S[i][strcspn(S[i], "\n")] = '\0';

    if (strlen(S[i]) < min) {
      min = strlen(S[i]);
    }
  }

  for (i = 0; i < N; i++) {
    S[i][min + 1] = '\0';
  }

  i = N - 1;

  do {
    strncpy(gra, S[i], min + 1);

    printf("%s ", gra);

    i--;
  } while (i >= 0);

  return 0;
}
arrays c string printf
1个回答
0
投票

代码的 main 问题是

scanf("%d", &N);
在读取
N
值后在输入缓冲区中留下换行符。因此,后续
for
循环的第一次运行读取空字符串,因此
min
值将设置为零。这里详细讨论了这个问题: scanf() 将换行符留在缓冲区中。清除此问题的一个简单方法是在读取
scanf("%*c");
和开始循环之间添加一条
N
行,但是链接问题的答案中还给出了其他方法。

修复后,您仍然遇到一些问题:请注意,在 C 中数组索引从 zero 开始;因此,要将字符串截断为仅

min
字符,您需要在
nul
处添加
'\0'
终止符 (
S[i][min]
),在 S[i][min+1] 处添加
not
,就像您所做的那样。

此外,添加终止符后,您不需要使用

strncpy
– 一个简单的
strcpy
就足够了。

这是包含上述修复的代码版本:

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

int main(void)
{
    int N, i;
    char S[100][51], gra[51];

    scanf("%d", &N);
    if (N < 1 || N > 100) {
        printf("Wrong Input");
        return 1;
    }
    scanf("%*c"); // Clear leftover newline from input buffer

    size_t min = 52; // The "size_t" type is a better fit for `strlen`
    for (i = 0; i < N; i++) {
        fgets(S[i], 51, stdin);
        S[i][strcspn(S[i], "\n")] = '\0';
        if (strlen(S[i]) < min) {
            min = strlen(S[i]);
        }
    }

    for (i = 0; i < N; i++) {
        S[i][min] = '\0'; // Array indexes start at zero, so add null at [min], not [min+1].
    }

    i = N - 1;
    do {
        strcpy(gra, S[i]); // Don't need strncpy: a nul terminator has been added to limit length
        printf("%s ", gra);
        i--;
    } while (i >= 0);

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.