【问题标题】:I want to break a string stored in an array at the '\n' character?我想在 '\n' 字符处破坏存储在数组中的字符串?
【发布时间】:2017-10-30 15:37:15
【问题描述】:

我的文件包含三行,在使用 fgets 将文件读入数组后,我想在换行符处打破三行并在控制台上分别打印三行,如果可能的话将三行存储在三个不同的数组。

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

 int main()
 {
    FILE *infile;
    char data[BUFSIZ],*pa,token_seperator[]={"\n"};

   infile=fopen("example","r");

   while((fgets(data,BUFSIZ,infile)!=NULL))

   pa=strtok(data,token_seperator);

   while(pa!=NULL) 
   {
    printf("%s\n",pa);
    pa=strtok(NULL,token_seperator);
   }
 }

【问题讨论】:

  • 执行fgets 3次。
  • char *app; app=strchr(data,'\n'); if (app!=NULL) *app=0; 在 Windows 上,您必须使用 '\r' 而不是 '\n' 进行截断。 (或者你可以同时测试 '\n' 和 '\r')。
  • 我看到第一个 while 读取所有文件直到最后......然后你只解析文件的最后一行!
  • fgets 手册页显示“在 EOF 或换行符后停止读取”。正如 BLUEPIXY 所说,执行 fgets 三次并每次打印/存储它

标签: c string fgets


【解决方案1】:

“在换行符处断三行”没有任何意义,因为一行不能包含超过一个换行符。

如果您需要读取单独数组中的每一行,则只需声明一个二维字符数组。如果您愿意,您可以通过调用fgets 删除附加到每一行的换行符。

所以程序可以如下所示。

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

#define N 3

int main( void )
{
    FILE *infile;
    char data[N][BUFSIZ];

    infile = fopen( "example", "r" );

    if ( infile )
    {
        size_t n = 0;
        for (; n < N && fgets(data[n], BUFSIZ, infile); n++)
        {
            data[n][strcspn(data[n], "\n")] = '\0';
        }

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

    return 0;
}

【讨论】:

  • 我想知道,如果我不知道我必须从文件中读取多少行并且我想使用 strlen 计算每行中的字符数怎么办?跨度>
  • if循环的条件是infile怎么来的? infile 是否曾经返回正整数或 0 以分别作为真或假执行循环?
  • @AMD 如果行数未定义,那么您需要动态重新分配一个二维字符串数组。对于 for 循环中的条件,如果指针不等于 NULL,则认为它为真。
【解决方案2】:

下面的函数truncCrLf 从 ASCII-0 字符串中删除第一次出现的 CR 和/或 LF 代码。这就是您要查找的内容,因为 fgets 函数会从文件中读取这些 ASCII 代码(0xA 和/或 0xD)。

此函数在 Linux 和 Windows SO 下都起作用。

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

char * truncCrLf(char *data)
{
    char *app=NULL;

    app = strchr(data, '\n');
    if (app)
      *app=0;

    app = strchr(data, '\r');
    if (app)
      *app=0;

    return data;
}

int main(void)
{
  char test[200];

  strcpy(test,"Hello world\n");

  printf("%s......\n",test);

  truncCrLf(test);

  printf("%s......\n",test);

  return 0;
}

【讨论】:

  • 更简洁的方法是将truncCrLf(test); 替换为test [ strcspn(test, "\r\n") ] = 0;
  • 我不知道这个...谢谢! :)
  • @WeatherVane。我试过你说的,但它没有运行!我也尝试使用 strcspn(test, "\n") 因为我在 Linux 下,但它没有运行。
【解决方案3】:

您需要分配一些内存来执行此操作,只是因为您不知道最终会有多少行,也不知道每行的大小。

我建议你下一个代码

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

typedef SplittedString char[BUFSIZ]

int main()
{
   FILE *infile;
   char token_seperator[]={"\n"};
   SplittedString data;
   SplittedString myLines[50];   // you can modify this number to hold more lines
   int i=0;
   infile=fopen("example","r");

   while((fgets(data,BUFSIZ,infile)!=NULL) && i < 50){ //prevent array overflow
       printf("%s\n",data);
       strcpy(myLines[i], data);
       ++i;
   }
 }

【讨论】:

  • fgets 在 EOF 或换行符之后停止。
  • 这不是唯一需要的改变。 *patoken_separator 类型错误。我建议你在发布之前编译。
  • @AndrejsCainikovs 我的错,我没有足够注意我在写什么,非常感谢!!
  • 我想知道你是否忘记声明一个名为 data 的数组?
  • 对不起伙计们,做事快永远不会结束XD
猜你喜欢
  • 2013-01-14
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 2022-12-01
  • 2016-03-17
  • 1970-01-01
  • 1970-01-01
  • 2023-02-16
相关资源
最近更新 更多