【问题标题】:Problem with 2D char arrays, program does not print二维字符数组有问题,程序不打印
【发布时间】:2019-02-10 16:04:27
【问题描述】:

在处理 2D 字符数组,我想创建一个火车列表,但这里似乎有问题,因为在我注册了 7 个名称后,程序将自动关闭。 .. 有人可以帮助我并解释我每次如何正确编写程序吗?谢谢。 **注意:***代码尚未完成*

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

#include <string.h>
#define N 7
#define M 20
int main()
{  FILE *fp;
   fp=fopen("Lines.txt","w");
    int i,n;
   char trains[N][M];
   char train[M];
  for(n=0;n<N;n++)
 {
     scanf("%s", train);
     strncpy(trains[n],train,M-1);

  }
  for(n=0;n<N;n++)
 {
     for(i=0;i<M;i++)
     {
         printf("%s\n", trains[n][i]);
     }

  }


  return 0;
}

【问题讨论】:

  • 嗨,欢迎来到 StackOverflow。它肯定会关闭,因为它循环了 N 次并且 N=7?

标签: c arrays file


【解决方案1】:

拥有

 char trains[N][M];

printf 中的

 for(i=0;i<M;i++)
 {
     printf("%s\n", trains[n][i]);
 }

无效,因为trains[n][i] 是一个字符,而您将其打印为字符串 (%s)

包括for的所有形式都可以替换为

 printf("%s\n", trains[n]);

否则你可以逐个字符地写,但是当你到达空字符时你需要停下来:

 for(i=0; trains[n][i] != 0 ; i++)
 {
     printf("%c", trains[n][i]);
 }
 putchar('\n');

你打开了一个文件,但你没有写入


你需要测试fopen的结果来检查文件是否打开


其他问题

 scanf("%s", train);
 strncpy(trains[n],train,M-1);

strncpy 不会复制最终的空字符

因为你有

字符训练[N][M]; 字符火车[M];

使用中间train是没用的,并且不提供受保护的(如果不超过trains[x],它的大小)

您需要检查 scanf 的返回值,最多可以读取 19 个字符 (M - 1):

if (scanf("%19s", trains[n]) != 1)
  break;

您无法保证您阅读了 7 列火车,因此您必须在之后更改循环:

for (i = 0; i != n; ++i)
  printf("%s\n", trains[n]);

在这种情况下你也可以使用 puts

如果你还想在打开的文件中写入

for (i = 0; i != n; ++i) {
  fprintf(sp, "%s\n", trains[n]);
  puts(trains[n]);
}

你的程序终于可以了

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

#define N 7
#define M 20

int main()
{ 
  FILE * fp=fopen("Lines.txt","w");

  if (fp == 0) {
    puts("cannot open Lines.txt");
    return -1;
  }

  int i,n;
  char trains[N][M];

  for(n = 0; n<N; n++)
  {
    if (scanf("%19s", trains[n]) != 1)
      break;
  }

  for(i = 0; i != n; ++i)
  {
      fprintf(fp, "%s\n", trains[i]);
      /*puts(trains[i]);*/
  }

  fclose(fp);
  return 0;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -g -pedantic -Wextra c.c
pi@raspberrypi:/tmp $ ./a.out
train1
train2
train3
train4
train5
train6
train7
pi@raspberrypi:/tmp $ cat Lines.txt 
train1
train2
train3
train4
train5
train6
train7
pi@raspberrypi:/tmp $ 

注意如果火车的名字超过19个字符就会被删掉,例如:

pi@raspberrypi:/tmp $ ./a.out
train1
verylongnameofatrain
train3
train4
train5
train6
pi@raspberrypi:/tmp $ cat Lines.txt 
train1
verylongnameofatrai
n
train3
train4
train5
train6
pi@raspberrypi:/tmp $ 

【讨论】:

  • 在这种情况下仍然是一个字符串,但不是作为完整的字符串打印,而是作为字符的组合,对吗?
  • @AvengerScarlet 如果你使用%s,参数必须char *
  • 如何将其制成 char*?对不起,我是新手,这对我来说很难
  • @AvengerScarlet 看看我的回答,我打印为 strong (%s) 和 char (%c)
  • no scanf("%s", trains) 不正确,因为 trains 是 char**,而不是 char*,看看我的答案,我对其进行了编辑并添加了完整程序的提案;我还管理错误案例
【解决方案2】:
  for(n=0;n<N;n++)
 {
     for(i=0;i<M;i++)
     {
         printf("%s\n", trains[n][i]);
     }

  }

应该是

  for(n=0;n<N;n++)
  {
         printf("%s\n", trains[n]);

  }

这是因为在您的字符数组trains 中,每一行都包含您输入的字符串。当您执行trains[n][i] 时,它会尝试访问字符串中的特定字符。

如果要打印每个字符,请尝试如下:

 for(n=0;n<N;n++)
 {
     for(i=0;i<M && trains[n][i]!='\0';i++)
     {
         printf("%c", trains[n][i]);
     }
     printf("\n");
  }

【讨论】:

  • 但是为什么呢?大学的时候看到老师用int v[N][M]做二维打印,是不是说char数组和int数组之间有一些变化?
  • 当他们执行 v[N][M} 时,他们将字符串中的字符打印为字符串本身。
猜你喜欢
  • 1970-01-01
  • 2018-09-29
  • 1970-01-01
  • 2017-04-11
  • 1970-01-01
  • 2016-02-15
  • 1970-01-01
  • 2011-04-10
  • 2017-12-29
相关资源
最近更新 更多