简体   繁体   English

C - 如何逐行读取字符串?

[英]C - How to read a string line by line?

In my C program, I have a string that I want to process one line at a time, ideally by saving each line into another string, doing what I want with said string, and then repeating.在我的 C 程序中,我有一个字符串,我想一次处理一行,理想情况下,将每一行保存到另一个字符串中,对所述字符串执行我想要的操作,然后重复。 I have no idea how this would be accomplished, though.不过,我不知道这将如何实现。

I was thinking of using sscanf.我正在考虑使用 sscanf。 Is there a "read pointer" present in sscanf like there would be if I was reading from a file? sscanf 中是否存在“读取指针”,就像我从文件中读取一样? What would be another alternative for doing this?这样做的另一种选择是什么?

Here's an example of how you can do it efficiently, if you are allowed to write into the long string: 如果允许您写入长字符串,这是一个如何有效地执行此操作的示例:

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

int main(int argc, char ** argv)
{
   char longString[] = "This is a long string.\nIt has multiple lines of text in it.\nWe want to examine each of these lines separately.\nSo we will do that.";
   char * curLine = longString;
   while(curLine)
   {
      char * nextLine = strchr(curLine, '\n');
      if (nextLine) *nextLine = '\0';  // temporarily terminate the current line
      printf("curLine=[%s]\n", curLine);
      if (nextLine) *nextLine = '\n';  // then restore newline-char, just to be tidy    
      curLine = nextLine ? (nextLine+1) : NULL;
   }
   return 0;
}

If you're not allowed to write into the long string, then you'll need to make a temporary string for each line instead, in order to have the per-line string NUL terminated. 如果你不允许写入长字符串,那么你需要为每一行创建一个临时字符串,以便终止每行字符串NUL。 Something like this: 像这样的东西:

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

int main(int argc, char ** argv)
{
   const char longString[] = "This is a long string.\nIt has multiple lines of text in it.\nWe want to examine each of these lines separately.\nSo we will do that.";
   const char * curLine = longString;
   while(curLine)
   {
      const char * nextLine = strchr(curLine, '\n');
      int curLineLen = nextLine ? (nextLine-curLine) : strlen(curLine);
      char * tempStr = (char *) malloc(curLineLen+1);
      if (tempStr)
      {
         memcpy(tempStr, curLine, curLineLen);
         tempStr[curLineLen] = '\0';  // NUL-terminate!
         printf("tempStr=[%s]\n", tempStr);
         free(tempStr);
      }
      else printf("malloc() failed!?\n");

      curLine = nextLine ? (nextLine+1) : NULL;
   }
   return 0;
}

Building on Jeremy Friesner's answer, here's what I came up with.基于 Jeremy Friesner 的回答,这就是我想出的。 First, a function for counting the number of lines:首先,一个 function 用于计算行数:

int countChar(char* str, char c) {
  char* nextChar = strchr(str, c);
  int count = 0;

  while (nextChar) {
    count++;
    nextChar = strchr(nextChar + 1, c);
  }

  return count;
}

Next, a function for copying the string into an array of lines:接下来,一个 function 用于将字符串复制到行数组中:

char** lineator(char* origin) {
  char* str = (char*) malloc(strlen(origin) + 1);
  strcpy(str, origin);

  int count = countChar(origin, '\n');
  char** lines = (char**) malloc(sizeof(char *) * count);

  char* nextLine = strchr(str, '\n');
  char* currentLine = str;

  int i = 0;

  while (nextLine) {
    *nextLine = '\0';

    lines[i] = malloc(strlen(currentLine) + 1);
    strcpy(lines[i], currentLine);

    currentLine = nextLine + 1;
    nextLine = strchr(currentLine, '\n');

    i++;
  }

  free(str);
  return lines;
}

Then I use these two functions to read the lines one by one.然后我用这两个函数一一读取行。 For example:例如:

int count = countChar (contents, '\n');
char** lines = lineator(contents);
const char equals[2] = "=";

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

I could of course use Mr. Freisner's answer.我当然可以使用 Freisner 先生的回答。 That would be more efficient and require fewer lines of code, but conceptually, I find this method a little easier to comprehend.这会更有效并且需要更少的代码行,但从概念上讲,我发现这种方法更容易理解。 I also neglected to deal with malloc failing.我也忽略了处理 malloc 失败的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM