我如何在C中修复它? [英] How do I fix that in C?

查看:84
本文介绍了我如何在C中修复它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 C 中使用 fsanf()命令打开并读取仅包含两行的文本文件。在第一行是一个整数N数,在第二行是第一行所说的N个整数。



例如。

I use the fsanf() command in C to open and read a text file that contains only two lines. in first line is an integer N number, and in the second line is the N integer numbers that the first line says.

Eg.

-------------- nubmers.txt --------------
8                                       <-- we want 8 numbers for the 2nd line
16 8 96 46 8 213 5 16                   <-- and we have 8 numbers! :)





如果第二行的数字多于或少于第一行,则整数表示会输出错误:



例如



Also if the second line have more or less numbers than the first line integer says will print an error:

Eg

-------------- nubmers.txt --------------
10
16 8 96 46 8 213 5 16 8 9 21 5 69 64 58 10 1 7 3 6







现在我将发布 fscanf()代码:




Now I will post the fscanf() code:

int num;

...

fscanf(fp,"%d",&num);
int i = 0;                                                      
int value = 0;                                                 

while (fscanf (fp, "%d", &value) == 1)         
{
    i++;                                                            
}

if (i > num)                                                  
{
    printf ( "too many integers\n");                                
    getchar();                                                      
    return 1;                                                       
}

if (i < num)                                                 
{
    printf ("not enough integers\n");                              
    getchar();                                                     
    return 1;                                                       
}

// if i equals num the code will get to this spot and will continue the debugging!

printf("work until now");                                       
getchar();                                                     
return 0;





但问题是这个。

假设我们想要第二行的 4 数字。在第二行,我们有 3个数字 1个字母



例如



But the problem is this.
Lets say that we want 4 numbers for the second line. And In the second line we have 3 numbers and 1 letter.

Eg

-------------- nubmers.txt --------------
4
3 2 1 p







然后代码将读取该字母,它将显示我们的整数较少。 - 因为字母 p 不是整数。

我想收到一条错误消息,说我们在文本文件中有一个字母而不是数字




Then the code will read the letter and it'll show that we have less integers. -cause the letter p isn't a integer.
I want to get an error message that will say we have a letter in the text file and not a number

推荐答案

查看 fscanf [ ^ ]返回值。

Check out the fscanf[^] return value.
...
int success = 1;
for(int i = 0; success && (i < num); ++i)
{
    if (fscanf(fp, "%d", &value))
    {
        // store value somewhere
        // ...
    }
    else
    {
        printf("failed to read value or too little values");
        success = 0;
    }
}
if (success && fscanf(fp, "%d", &value))
{
    printf("too many values");
}
...



干杯

Andi


Cheers
Andi


按顺序要做你想做的事你不应该通过fscan的%d格式读取值,而只是将字符串标记化,即将其细分为字符串。你可以用fscan的%s格式做到这一点,虽然我更喜欢其他方法。所以你的循环可能如下所示:

In order to do what you want you should not read the values via fscan's %d format, but just tokenize the string, i.e. subdivide it into strings. You can do that with fscan's %s format, although I would prefer other means. So your loop could look like:
// improved code, but not really good; see below
char str[100];
int value;

while (fscanf (fp, "%s", &str) == 1)         
{
    if (sscanf (str, "%d", &value) == 1)
        i++;
    else
        printf ("Input <%s> is not a number", str);
}



有两个原因,为什么我不喜欢 scanf 函数:一个他们无法控制处理新行。换行符只是另一个空格字符。所以,如果您的输入是


There are two reasons, why I don't like the scanf functions: For one they offer no control over handling newlines. A newline is just another whitespace character. So if your input would be

5
12 56 89
34 52



它将被视为合法投入。第二个原因是本质上不安全,因为你不能为%s格式指定输入缓冲区的长度(我在上面的例子中输入了100)。



作为scanf的替代方案,我更愿意先用 fgets 逐行读取输入行。然后通过 strtok 解析该行,最后通过 strtol 将其转换为整数。


it would be regarded as legal input. The second reason is that is inherently unsafe, as you cannot specify the length of your input buffer for the %s format (I put in 100 in the example above).

As an alternative to scanf I would prefer to first read the input line by line with fgets. Then parse the line by strtok, and finally convert it to integers by strtol.


#include "stdafx.h"

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


char  *fname ="E:\\00-C++\\VC2010\\PROJEKTE\\testfile.txt"; //filepath with the numbers
const int   first_min       =3;  //min number count for line 2
const int   first_max       =12; //max number count for line 2
      int   first_number    =0;
const long  second_min      =100;
const long  second_max      =1000000;

const int   max_linelength  =100;  // make sure that real file-line-length is shorter than max_linelength
      char  line[max_linelength+5];
      int   lineno          =0;

      long  number[first_max+5];
      int   ixnumber        =0;

//--------------------------------------------------------------------------------
void funcPrintRuler()
{
  printf("\n");
  printf("\n.........1.........2.........3.........4.........5.........6.........7.........8.........9");
  printf("\n123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
}

//--------------------------------------------------------------------------------
int funcOnlyDigitsOrSpaceAllowed(int lineno,char *line)
{
  int   kzdigit =0;
  int   pos     =0;
  char  *p      =line;

  while (NULL!=*p)
  {
    pos++;
    if (isdigit(*p))  {kzdigit=1;p++;continue;}
    if (' '==*p)      {p++;continue; }

    funcPrintRuler();
    printf("\n%s",line);
    printf("\n%d.line: Only digits or space allowed. pos=%d",lineno,pos);
    printf("\n");
    return 0;
  }

  if (0==kzdigit)
  {
    funcPrintRuler();
    printf("\n%s",line);
    printf("\n%d.line: digits are missing",lineno);
    printf("\n");
    return 0;
  }
  return 1;
}

//--------------------------------------------------------------------------------
void funcGetNumbers(int lineno,char *line)
{
  char  *p  =line;
  ixnumber  =0;

  while (NULL!=*p )
  {
    if (ixnumber>=first_max) return ; // too many numbers
    if (' '==*p) {p++; continue;}

    number[ixnumber]=atol(p);
    while( NULL!=*p && isdigit(*p))  {p++; continue;} // goto next number
    ixnumber++;
    p++;
  }
}

//--------------------------------------------------------------------------------
int funcCheckLine1(int lineno,char *line)
{
  funcGetNumbers(lineno,line);
  if (1!=ixnumber )
  {
    printf("\n%d.line=%s<",lineno,line);
    printf("\nonly one number allowed");
    return 0;
  };

  if ( number[0]<first_min || number[0]>first_max )
  {
    printf("\n%d.line=%s<",lineno,line);
    printf("\n%d.line contains number=%d,  but must be >=%d and <=%d",lineno,number[0],first_min,first_max);
    return 0;
  }
  return 1;
}

//--------------------------------------------------------------------------------
int funcCheckLine2(int lineno,char *line)
{
  int i;
  funcGetNumbers(lineno,line);
  if (ixnumber!=first_number )
  {
    printf("\n%d.line=%s<",lineno,line);
    printf("\nnumber count=%d, but must be %d",ixnumber, first_number);
    return 0;
  };
  for(i=0; i<ixnumber;i++)
  {
    if (number[i]<second_min || number[i]>second_max )
    {
      printf("\n%d.line=%s<",lineno,line);
      printf("\nnumber %d=%d, but must be >=%d and <=%d",i+1,number[i],second_min,second_max);
      return 0;
    }
  }
  return 1;
}

//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
  int   i;
  FILE  *fp;
  int   lg=0;

  printf("START");
  
  fp = fopen (fname, "r");
  if (fp == NULL) { printf ("Cannot open: \n%s",fname); goto w_err;}

  while (NULL != fgets(line, max_linelength, fp))
  {
    lineno++;
    lg=strlen(line);
    line[lg-1]='\0'; // remove '\n', only for printf line, not nessessary for read numbers
    //printf("\n%d. line=%s<",lineno,line);

    switch( lineno )
    {
      case 1:
        if ( !funcOnlyDigitsOrSpaceAllowed(lineno,line) ) goto w_err;
        if ( !funcCheckLine1(lineno,line) )               goto w_err;
        first_number=number[0];
      break;
      case 2:
        if ( !funcOnlyDigitsOrSpaceAllowed(lineno,line) ) goto w_err;
        if ( !funcCheckLine2(lineno,line) )               goto w_err;
      break;
      default:
        // do something
        printf("\n%d.line=%s<",lineno,line);
    }
  }
  fclose (fp);


w_ok:
  printf("\n\nFile Content:");
  printf("\nline 1 read %d=number count for line 2",first_number);
  for (i=0; i<ixnumber; i++)
  {
    printf("\nline 2 read %d.number=%ld",i+1,number[i]);
  }
  printf("\nprogram OK");

  getc(stdin); // only pause
  exit(EXIT_SUCCESS);

w_err:
  printf("\nprogram error");
  getc(stdin);
  exit(EXIT_FAILURE);
}


这篇关于我如何在C中修复它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆