我想要做的是读取文件的第一行,但是在第一行之后只读取以下行直到命中空格。我的最终目标是通过向所述行添加/减去时间来询问用户他们想要编辑的行。
示例文件
My test file
00:19.1 123456
00:35.4 testing whitespace end
期望输出
1: My test file
2: 00:19.1
3: 00:35.4
代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fptr1, *fptr2;
char filechar[40];
char c[50];
int line_number = 1;
int replace_line, temp = 1;
printf("Please enter a file name: ");
scanf("%s", &filechar);
if ((fptr1 = fopen(filechar, "r")) == NULL)
{
printf("Error locating desired file");
exit(1);
}
c = getc(fptr1);
while (c != EOF)
{
//printf("%d: %c",line_number, c);
printf("%s",c);
c = getc(fptr1);
//line_number++;
}
return 0;
}
答案 0 :(得分:2)
在C中你有面向字符的输入函数(例如getchar
,fgetc
),你有格式化的输入函数(例如{{ 1}} family)然后你有面向行的输入函数。 (例如scanf
和POSIX fgets
)。当您阅读行数据时,面向行的输入函数是该作业的正确工具。 (用getline
获取用户输入有许多陷阱,新的(甚至不是那么新的)C程序员陷入其中)
所有面向行的函数在它们填充的缓冲区中读取并包含 scanf
。如果稍后将在代码中使用换行符,则可以而且应该从结果缓冲区中删除换行符。一个简单的
'\n'
您只需用 nul-terminatedating 字符覆盖尾随size_t n = strlen (buf);
if (buf[n-1] == '\n')
buf[--n] = 0;
即可。如果您只是立即打印该行而不是存储它以供以后使用,那么不值得删除换行符(只需在输出格式字符串中考虑它)。
将这些部分组合在一起,您可以读取每一行,只需输出它就可以处理第一行,并且对于每个剩余的行,从读取的完整字符串中解析时间(可能需要一些经过时间)。带有'\n'
的{{1}}并根据您的指定格式化输出。 E.g。
fgets
注意:您应该通过在sscanf
格式字符串中包含字段宽度说明符来防止解析时的缓冲区溢出(例如#include <stdio.h>
#define MAXC 64 /* define constants, don't use magic number in code */
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* buffer to hold each line -- size as reqd */
int line = 1;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, sizeof buf, fp)) { /* read each line in file */
char et[MAXC] = ""; /* buffer for holding time */
if (line == 1) /* if 1st line, just print */
printf ("%d : %s", line, buf); /* note: \n included by fgets */
else {
if (sscanf (buf, "%s", et) != 1) { /* parse up to first whitespace */
fprintf (stderr, "error: invalid conversion, line %d\n", line);
return 1;
}
printf ("%d : %s\n", line, et); /* output elapsed time only */
}
line++; /* increment line count */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
,您可以在代码中包含幻数,因为无法直接为sscanf
指定可变宽度说明符,除非您创造性地使用{ {1}}提前创建格式字符串 - 但这是另一天...
示例输入文件
sscanf (buf, "%63s", et)
示例使用/输出
sscanf
仔细看看,如果您有任何其他问题,请告诉我。
(注意:我将文件名作为程序的第一个参数,或者如果没有给出文件名,则从sprintf
读取.C提供命令行参数 - 使用它们。如果输入,则可以提示输入需要,否则,只需在命令行$ cat dat/et.txt
My test file
00:19.1 123456
00:35.4 testing whitespace end
答案 1 :(得分:0)
如果此C代码可以帮助您,请尝试。它只是逐行读取文件,并用字符串终止字符\0
替换空格。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
char* replace_char(char* str, char find, char replace){
char *current_pos = strchr(str,find);
while (current_pos){
*current_pos = replace;
current_pos = strchr(current_pos,find);
}
return str;
}
int main(void)
{
FILE * fp;
char * line = NULL;
size_t len = 0;
ssize_t read;
fp = fopen("/home/developer/CLionProjects/untitled4/download.out", "r");
if (fp == NULL)
exit(EXIT_FAILURE);
int count=0;
while ((read = getline(&line, &len, fp)) != -1) {
if (count==0) printf("%s", line);
else printf("%s\n", replace_char(line, ' ', '\0'));
count++;
}
fclose(fp);
if (line)
free(line);
exit(EXIT_SUCCESS);
}
文件
My test file
00:19.1 123456
00:35.4 testing whitespace end
输出
My test file
00:19.1
00:35.4