从文本文件中读取时如何忽略空格?

时间:2015-04-19 23:17:18

标签: c

我想修复我的C程序,忽略名称前面的额外空格。

例如,当从stdin读取的输入为:

11, Alan Turing,3.20

第一个逗号和名称之间有一个空格。我想忽略此空格并将以下行附加到student.txt

11,Alan Turing,3.20

这是我的代码:

#include <stdio.h>
#include <string.h>
typedef struct student {
    int id;
    char name[300];
    float grade;
}Student;

int main() {
   Student s;
   FILE *fp;
   fp = fopen("student.txt","a+");
   scanf("%d",&s.id);
   scanf("%[^1234567890]s",&s.name);
   s.name[strlen(s.name) - 1] = '\0';
   scanf("%f",&s.grade);
   fprintf(fp,"%d,%s,%.2f\n",s.id,s.name,s.grade);
   fclose(fp);
   return 0;
}

5 个答案:

答案 0 :(得分:0)

第二个scanf中的扫描集会读取所有非数字字符。这不是你想要做的。您想要阅读下一个逗号的所有字符。

尝试用以下内容替换您的三个scanf来电:

scanf("%d, ", &s.id);
scanf("%[^,]", &s.name);
scanf(",%f", &s.grade);

并取消你之间的任务。

请注意,第一个scanf中的空格字符可以删除不需要的空格。

答案 1 :(得分:0)

我写了一个快速解析器,这个读取一个int skip非alpha char,存储所有char直到找到一个数字然后解析一个浮点数

stdin解析后我没有做任何修改。 标准输入:

45 foo bar 45.69
 45, toto, 78.5

标准输出:

ID:45
NAME:foo bar
GRADE:45.69
ID:45
NAME:toto
GRADE:78.50

文件内容:

45,foo bar,45.69
45,toto,78.50

PROG:

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

typedef struct student {                                                       
    int id;                                                                    
    char name[256]; /* use aligned structures*/                                
    float grade;                                                               
} Student;                                                                     

int main() {                                                                   
    Student s;                                                                 
    FILE *fp;                                                                  
    char buf[BUFSIZ];                                                          
    char *p;                                                                   
    int i = 0;                                                                 

    fp = fopen("student.txt", "a+");                                           
    printf("Give id name and grade\n");                                        
    fgets(buf, sizeof(buf), stdin);                                            


    p = buf;                                                                   
    /* get id */                                                               
    s.id = strtol(p, &p, 10);                                                  
    if (!s.id) {                                                               
        fprintf(stderr, "Bad id");                                             
        return -1;                                                             
    }                                                                          
    /* skip non alpha char between int and name*/                              
    while (!isalpha(*p)) {                                                     
        p++;                                                                   
    }                                                                          

    /*copy name */                                                             
    while (!isdigit(*p)) {                                                     
        s.name[i++] = *p++;                                                    
    }                                                                          
    if (i == 0) {                                                              
        fprintf(stderr, "Bad name");                                           
        return -1;                                                             
    }                                                                          
    s.name[i] = '\0';                                                          
    i--;                                                                       
    /*remove trailing char at the end of the name */                           
    while(!isalpha(s.name[i])) {                                               
        s.name[i--] = '\0';                                                    
    }                                                                          
    /* parse grade */                                                          
    s.grade = strtof(p, &p);                                                   


    fprintf(fp,"%d,%s,%.2f\n",s.id,s.name,s.grade);                            
    fclose(fp);                                                                
    fp = fopen("student.txt","r");                                             
    if(fp != NULL) {                                                           
        while((fscanf(fp,"%d,%299[^,],%f", &s.id,s.name,&s.grade)) == 3) {     
            printf("ID:%d\n",s.id);                                            
            printf("NAME:%s\n",s.name);                                        
            printf("GRADE:%.2f\n",s.grade);                                    
        }                                                                      
        fclose(fp);                                                            
    } else  {                                                                  
        perror("student.txt");                                                 
    }                                                                          
    return 0;                                                                  
}

答案 2 :(得分:0)

要删除字符串中的字符,您必须在逗号后面替换以下字符。

最终可能会得到类似下面的函数,而它们是解决这个问题的许多其他方法,我觉得这个方法简单而有效。

void
trim_comma_spaces(char *string)
{
        char   *tmp;
        char   *ptr    = string;
        int    i;
        size_t len;

        ptr = string;
        while(1) {
                tmp = strchr(ptr, ',');

                if(!tmp)
                        break;

                for(i=0, tmp++; isspace(*(tmp+i)); i++);

                if(!i) {
                        ptr = tmp + 1;
                        continue;
                }

                len = strlen(tmp);

                /* memory areas may overlap? Use memmove */
                memmove(tmp, tmp+i, len - i);

                *(tmp + len - i) = '\0';

                ptr = tmp;
        }
}

例如

int
main(void)
{
        char *ptr;
        char *tmp;
        char string[] = "11,     \n\n\r\v\f      Alan Turing, 3.20\n12, \n\v\fJohn Doe, 3.19";

        printf("Before:\n%s\n", string);
        trim_comma_spaces(string);

        printf("after:\n%s\n", string);
        return 0;
}

输出:

Before:
11,



      Alan Turing, 3.20
12,


John Doe, 3.19
after:
11,Alan Turing,3.20
12,John Doe,3.19

答案 3 :(得分:0)

建议从使用fgets()阅读开始。

现在使用"%d , %299[A-Za-z ] ,%f"扫描缓冲区。请务必测试ssscanf()结果。

"%d"阅读任何空格,阅读int " , "阅读任何空格,逗号,任何空白区域 "%299[A-Za-z ]"读取最多299个字母或空格字符串 或者根据需要在名称中找到其他char(例如-'."%299[-A-Za-z '.]" @BLUEPIXY
" ,"阅读任何空白处,逗号 "%f"阅读任何空格,阅读浮点数。

#include <stdio.h>
#include <string.h>
typedef struct student {
  int id;
  char name[300];
  float grade;
} Student;

int main(void) {
  Student s;
  FILE *fp;
  fp = fopen("student.txt", "a+");

  // Read line, =uses a buffer about twice expected need
  char buf[sizeof s * 2];  
  fgets(buf, sizeof buf, stdin);

  // 11, Alan Turing,3.20
  int cnt = sscanf(buf, "%d , %299[A-Za-z ] ,%f", &s.id, s.name, &s.grade);
  if (cnt != 3) {
    fprintf(stderr, "Unexpected input, cnt = %d\n", cnt);
    fclose(fp);
    return 1;
  }
  fprintf(fp, "%d,%s,%.2f\n", s.id, s.name, s.grade);
  fclose(fp);
  return 0;
}

答案 4 :(得分:0)

我写了一个跳过空格的函数。

//function to skip space while reading from file
void skip_space(FILE *fp)
{
    char tmp;
    do
    {
        fscanf(fp, "%c", &tmp);
    } while (isspace(tmp) || feof(fp)); 

    fseek(fp, -1, SEEK_CUR);
}

您可以在任何想要忽略空格的地方调用此函数。

相关问题