簡體   English   中英

ASCII字符未打印出來

[英]ASCII characters not getting printed out

我想從輸入文件中讀取卡並打印出它們的值。

但是,當我嘗試打印出字符時,它會打印出'0'

如果我打印出字符'A' ,則通常應該打印出int值65 ,因為我將字符'A'存儲為Int。

有人可以幫我嗎?

先感謝您。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 100
#define MAX_LENGTH 14

int main(){
  char *lines = malloc(max*sizeof(char));

    char **colour = malloc(max*sizeof(char));
    int *value =malloc(max*sizeof(int));
    FILE *fp;
    fp = fopen("config2.txt", "r");
    if(fp == NULL){
        printf("Cannot open filelist.txt\n");
        return 1;
    }
    int i= 0;
    while (i < max && fgets(lines, MAX_LENGTH, fp) != NULL) { 
        colour[i] = malloc(MAX_LENGTH); 
        sscanf(lines, "%s %d", colour[i], &value[i]);
        printf("%s\n", colour[i]);
        printf("%d\n", value[i]);

        i++;
    }
    return 0;
}

輸入:

RED A
RED 2
RED 3
RED 4
RED 5
RED 6
RED 7
RED 8
RED 9
RED 10
RED J
RED Q
RED K

處理'A'或作為值的整數的主要問題是由於人們誤解了A可以使用sscanf使用"%d" 格式說明符來解析,而不能。 為什么? 當您嘗試使用"%d"解析'A'時, 發生匹配失敗 ,從輸入緩沖區中不再提取任何字符,而sscanf返回將是失敗之前發生的成功轉換的次數。

當您擁有不同類型的數據時,例如

RED A
RED 2

為了解析A2的值,將需要兩個不同的sscanf表達式,您可以通過檢查 sscanf 返回值來輕松區分它們。 您有條件地執行此操作,如果使用"%s %d"解析失敗,則嘗試使用"%s %c"進行解析並驗證是否成功。

例如,說而不是使用malloc進行分配(無論如何您都不會重新分配),您只需聲明一個結構數組即可保存從每一行讀取的colorvalue ,例如

...
#define MAXCOLR   14
#define MAXLINE  100
#define MAXCHR  1024    /* don't skimp on read buffer size */

typedef struct {        /* simple struct to associate each color/value */
    char color[MAXCOLR];
    int value;
} colorval_t;

int main (int argc, char **argv) {

    size_t ndx = 0;     /* index */
    char buf[MAXCHR];   /* read buffer */
    colorval_t arr[MAXLINE] = {{ .color = "" }};    /* array of struct */
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
    ...
    while (ndx < MAXLINE && fgets (buf, MAXCHR, fp)) {
        char c;     /* temp char to use for parsing 2nd case */
        if (sscanf (buf, "%13s %d", arr[ndx].color, &arr[ndx].value) == 2)
            ndx++;
        else if (sscanf (buf, "%13s %c", arr[ndx].color, &c) == 2) {
            arr[ndx].value = c;
            ndx++;
        }
    }

上面的while循環是用於處理從每一行讀取到buf的信息的解析的操作代碼。 第一個sscanf調用嘗試將解析解析為字符串和整數值。 如果返回值不是2 ,則第二次調用sscanf嘗試將內容解析為字符串和字符。 如果成功,則將字符值(例如,字符的ASCII值)分配給value ,這在您的問題中似乎是您想要的。

添加一些驗證,然后為arr包含的每個結構輸出colorvalue ,您可以執行以下操作。 注意:該程序將文件名作為第一個參數讀取,或者如果未提供任何參數,則默認情況下從stdin讀取。不要對文件名進行硬編碼。將文件名作為參數傳遞或提示其輸入)

#include <stdio.h>

#define MAXCOLR   14
#define MAXLINE  100
#define MAXCHR  1024    /* don't skimp on read buffer size */

typedef struct {
    char color[MAXCOLR];
    int value;
} colorval_t;

int main (int argc, char **argv) {

    size_t ndx = 0;
    char buf[MAXCHR];
    colorval_t arr[MAXLINE] = {{ .color = "" }};
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    while (ndx < MAXLINE && fgets (buf, MAXCHR, fp)) {
        char c;
        if (sscanf (buf, "%13s %d", arr[ndx].color, &arr[ndx].value) == 2)
            ndx++;
        else if (sscanf (buf, "%13s %c", arr[ndx].color, &c) == 2) {
            arr[ndx].value = c;
            ndx++;
        }
    }
    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    for (size_t i = 0; i < ndx; i++)
        printf ("arr[%2zu] : %-14s %d\n", i, arr[i].color, arr[i].value);

    return 0;
}

注意:使用field-width修飾符13保護color的字符數組邊界)

使用/輸出示例

將您的數據用作輸入將導致以下結果:

$ ./bin/rdcolorval <dat/colorval.txt
arr[ 0] : RED            65
arr[ 1] : RED            2
arr[ 2] : RED            3
arr[ 3] : RED            4
arr[ 4] : RED            5
arr[ 5] : RED            6
arr[ 6] : RED            7
arr[ 7] : RED            8
arr[ 8] : RED            9
arr[ 9] : RED            10
arr[10] : RED            74
arr[11] : RED            81
arr[12] : RED            75

仔細檢查一下,如果您還有其他問題,請告訴我。

以下建議的代碼:

  1. 不保留每一行的內容,而僅保留當前行的內容。 您可能要更改
  2. 正確檢查錯誤
  3. 不使用動態內存分配。 您可能要更改
  4. 干凈地編譯
  5. 不包括頭文件,不使用那些內容
  6. 正常退出或調用sscanf()失敗時,正確清理(關閉文件)。
  7. main()使用有效的簽名
  8. 使用所有大寫字母的定義值慣例
  9. 在輸入格式說明符%s上正確使用MAX CHARACTERS修飾符,以避免任何可能的緩沖區溢出和導致的未定義行為
  10. 說明為什么要包含每個頭文件
  11. 不能糾正傳入數據和對sscanf()的調用之間的不匹配,強烈建議您閱讀有關atoi()strtol()並修改對sscanf()的調用,以期獲得兩個字符序列並相應地保存它們。

現在,建議的代碼:

#include <stdio.h>   // printf(), fprintf(), sscanf()
#include <stdlib.h>  // exit(), EXIT_FAILURE


//#define MAX_LINES 100
#define MAX_LENGTH 14


int main( void )
{
    char lines[ MAX_LENGTH +1];
    char colour[ MAX_LENGTH ];

    int  value;

    FILE *fp = fopen( "config2.txt", "r" );
    if(fp == NULL)
    {
        perror( "fopen to read config2.txt failed" );
        exit( EXIT_FAILURE );
    }


    while ( fgets( lines, MAX_LENGTH, fp ) ) 
    {   
        if( sscanf(lines, "%100s %d", colour, &value) != 2 )
        {
            fprintf( stderr,  "sscanf to extract two fields from input line failed\n" );
            fclose( fp );
            exit( EXIT_FAILURE );
        }

        printf( "colour: %s\n", colour );
        printf( "value:  %d\n", value );
    }
    fclose( fp );
    return 0;
}

您的代碼幾乎可以正常工作。 主要問題是您不能使用格式說明符“%s%d”來掃描“ RED A”之類的行,因為A不是整數。 相反,您可以使用char對其進行掃描。

此外,您對colourmalloc有問題。 需要一個char指針數組時,需要執行sizeof(char*)

因此,嘗試類似:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 100
#define MAX_LENGTH 14

int main(){
  char *filename = "config2.txt";
  char *lines = malloc(max*sizeof(char));
  char **colour = malloc(max*sizeof(char*));  // Use sizeof(char*)
  char *value =malloc(max*sizeof(char));      // Use char instead of int
  FILE *fp;

  fp = fopen(filename, "r");
  if(fp == NULL){
    fprintf(stderr, "Cannot open %s : ", filename);
    perror("");
    exit(1);
  }

  int i= 0;
  while (i < max && fgets(lines, MAX_LENGTH, fp) != NULL) {
    colour[i] = malloc(MAX_LENGTH);
    if (sscanf(lines, "%s %c", colour[i], &value[i]) != 2)  // Use %c instead of %d and check return value
    {
      printf("Unexpected input file data\n");
      exit(1);
    }
    printf("%s ", colour[i]);
    printf("%c (%d)\n", value[i], value[i]);       // Print value as both char and int

    i++;
  }

  // Clean up
  fclose (fp);
  for (int j = 0; j<i; ++j) free(colour[j]);
  free(colour);
  free(value);

  return 0;
}

輸出:

RED A (65)
RED 2 (50)
RED 3 (51)
RED 4 (52)
RED 5 (53)
RED 6 (54)
RED 7 (55)
RED 8 (56)
RED 9 (57)
RED 1 (49)
RED J (74)
RED Q (81)
RED K (75)

還要注意,您應該始終檢查malloc的返回值。 例:

SomeType *someVar = malloc(sizeof(SomeType));  // or better malloc(sizeof *momeVar);
if (someVar == NULL)
{
    // Out of memory - add error handling (e.g. terminate program)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM