基本上,我需要读取一个文本文件,并且只打印完整的行,但不包括以注释或空格开头的任何内容。我很难忽略注释,或者基本上忽略;
之后直到\n
字符之后的内容。这将指示该行的结尾。
我认为该代码可以正常工作,但在注释后仍会打印出来,
char* t=strtok(line,"\n ,.; ");
while(t != NULL ) {
if(t == ";"){
t = strtok(NULL," ");
while(t != NULL && t!="\n") {
t = strtok(NULL, "");
}
}
else
{
printf("%s\n",t);
t = strtok( NULL, "\n ,.; \n");
}
}
}
这是完整的代码:
int main()
{
char line [5000];
FILE *fp;
fp=fopen("gt.txt", "r");
if (fp == NULL)
perror ("error opening file");
else{
while(fgets (line, sizeof (line), fp)){
char* t=strtok(line,"\n ,.; ");
while(t != NULL ) {
if(t == ";"){
t = strtok(NULL," ");
while(t != NULL && t!="\n") {
t = strtok(NULL, "");
}
}
else
{
printf("%s\n",t);
t = strtok( NULL, "\n ,.; \n");
}
}
}
}
fclose(fp);
return(0);
}
这是我打印的内容,也用作下面的文本文件:
hello
goodbye
error
interesting
comment
wonderful
分号是文本文件中的真实分号:
hello
goodbye
(semicolon) error
(semicolon) error
interesting (semicolon) comment
wonderful
预先感谢
答案 0 :(得分:2)
仅打印完整行,不包括以注释或空格开头的任何内容
OP的if(t == ";"){
不是必需的功能。 @Craig Estey。确保启用所有警告以节省时间。
这会将指针char *t
与";"
进行比较,OP可能希望比较指向的字符串的内容,或者如果*t
是';'
则可能要进行比较。
有时state machine是一种很好的简单方法。跟踪行尾。在开始新行previous == '\n'
时,请检查它是否为空白行。
#include <ctype.h>
#include <stdio.h>
#define COMMENT_CHAR (';')
int main(void) {
FILE *fp = fopen("gt.txt", "r");
if (fp == NULL) {
perror("error opening file");
return EXIT_FAILURE;
}
bool blank_the_line = false;
int previous = '\n';
int ch;
while ((ch = fgetc(fp)) != EOF) {
if (previous == '\n') {
blank_the_line = isspace(ch) || ch == COMMENT_CHAR;
}
if (!blank_the_line) {
fputc(ch, stdout);
}
previous = ch;
}
fclose(fp);
return EXIT_SUCCESS;
}
注意:没有行长限制。
答案 1 :(得分:0)
请注意,t == ";"
可能[无效],甚至无法使用-Wall
干净地编译:
orig.c: In function ‘main’:
orig.c:19:11: warning: comparison with string literal results in unspecified behavior [-Waddress]
if (t == ";") {
^~
orig.c:21:28: warning: comparison with string literal results in unspecified behavior [-Waddress]
while (t != NULL && t != "\n") {
^~
if (t == ";")
将t
中包含的地址与字符串文字";"
的地址进行比较。这样做不会不测试t
指向的内容与字符串";"
的相等性,并且几乎不会产生期望的结果。>
比较字符串的通常方法是使用strcmp
等。 al(例如)if (strcmp(t,";") == 0)
。它将t
指向的 content 与字符串进行比较。
假设;
是您的注释字符,则将其添加到strtok
调用的定界符arg中是不正确的,因为它将在具有 some 有效文本和以结尾的注释结尾。
注释 char 将被删除,但是从strtok
返回的令牌将不再包含该注释。 ;
之后返回的令牌将是其后的第一个令牌(即 comment 的第一个令牌)。但是,我们将无法检测到这一点,因此我们将打印整行-而不是我们想要的。
因此,需要对注释字符进行单独扫描,以去除注释字符和后续文本 ,然后用strtok
这是应该工作的清理版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(void)
{
char line[5000];
FILE *fp;
char *cp;
char *bp;
char *sep;(i.e. we will strip the
fp = fopen("gt.txt", "r");
if (fp == NULL) {
perror("error opening file");
exit(1);
}
while (fgets(line, sizeof(line), fp)) {
// strip comment from right side of line (do this _before_ token scan)
cp = strchr(line,';');
if (cp != NULL)
*cp = 0;
// set up for token scan
bp = line;
sep = "";
// output all valid tokens on the line
while (1) {
// locate next token
cp = strtok(bp," ,.\t\n");
bp = NULL;
// stop if didn't find one
if (cp == NULL)
break;
// print the token
printf("%s%s",sep,cp);
// separate tokens by a space
sep = " ";
}
// end line that had _valid_ data
if (sep[0] != 0)
printf("\n");
}
fclose(fp);
return 0;
}