【问题标题】:C: Incorrect characters are being printed, suspected mem. issueC:正在打印不正确的字符,怀疑是内存。问题
【发布时间】:2016-11-01 02:10:00
【问题描述】:

我遇到了一些有趣的事情,奇怪的字符被打印出来,而不是我所期望的。它之前没有这样做,但我开始使用 fgets 和 sscanf,现在它不会恢复到原来的样子。我猜我在某处损坏了内存,或者在标准输入缓冲区中留下了一些东西,但不太确定。有什么想法吗?

我的期望:

***************************************************************************
*                                                                         *
*                                                                         *
*    1) What char for border?                                             *
*    2) Add question                                                      *
*    3) Remove Question                                                   *
*    4) Print last answers                                                *
*    5) Exit                                                              *
*                                                                         *
*                                                                         *
*                                                                         *
*                                                                         *
***************************************************************************

实际打印的是什么(如您所见,它打印了一个时髦的 y 并占用了一个空间):

***************************************************************************
*                                                                         *
*                                                                         *
*    1) What char for border?                                             *
*    2) Add question                                                      *
*    3) Remove Question                                                   *
*    4) Print last answers                                                *
*    5) Exit                                                              *
*                                                                         *
*    ÿ                                                                   *
*                                                                         *
*                                                                         *
***************************************************************************

这是我的代码:

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

typedef struct f_in{
    char outline;
    int lines;
    int rows;
    int num_args;
} F_IN;

typedef struct args_in {
    char in_string[20];
    int t_format;
} ARGS_IN;

void printInterface(char argQs[5][50], char argChar);

int main(int argv, char** argc){
    char defaultQuestions[5][50] = { { "1) What char for border?" }
        , { "2) Add question" }
        , { "3) Remove Question" }
        , { "4) Print last answers" }
    , { "5) Exit" } };
    int commandEntry, exitFlag, i;
    char borderChar = '*', addQ[50], userInp[10];

    exitFlag = 1;

    while (exitFlag){
        printInterface(defaultQuestions, borderChar);

        // GET INITIAL INPUT FROM USER
        printf("Enter the integer value for the command you wish to select:  ");
        fgets(userInp, sizeof(userInp), stdin);
        // VERIFY INPUT IS VALID
        sscanf(userInp, "%d", &commandEntry);
        printf("\nYou selected: %s\n", defaultQuestions[commandEntry - 1]);

        if (commandEntry == 1){
            printf("Please enter the character you wish to be the border:  ");
            scanf("\n%c", &borderChar);
        }
        else if (commandEntry == 2){
            printf("What question would you like to add? (only enter 50 char max)\n");
            fgets(addQ, 50, stdin);
            printf("This was your question: %s", addQ);
        }
        else if (commandEntry == 5){
            printf("Goodbye!\n");
            exitFlag = 0;
        }
    }
    return 0;

}

void printInterface(char argQs[5][50], char argChar){
    int i, j;
    int lineCnt = 13;
    int borderLen = 75;

    for (i = 0; i<100; i++){
        printf("\n");
    }

    for (i = 0; i<lineCnt; i++){

        if (i == 0 || i == lineCnt - 1){
            for (j = 0; j<borderLen; j++){
                printf("%c", argChar);
            }
            printf("\n");
        }

        else if (i >= 3 && i <= 10){
            printf("%c    %s", argChar, argQs[i - 3]);
            for (j = 0; j < ((borderLen - strlen(argQs[i - 3]))-6); j++){
                printf(" ");
            }
            printf("%c\n", argChar);
        }

        else{
            for (j = 0; j<borderLen; j++){
                if (j == 0){
                    printf("%c", argChar);
                }
                else if (j == (borderLen - 1)){
                    printf("%c\n", argChar);
                }
                else{
                    printf(" ");
                }
            }
        }
    }

    for (i = 0; i<10; i++){
        printf("\n");
    }

}

【问题讨论】:

  • 听起来你是在正确的轨道上。你需要不断调试,不要指望别人为你做!
  • (不要写,从不呈现未注释的代码。一旦你弄清楚垃圾来自哪里(提示:它不是来自乱码),请尝试 make @987654324 @为你处理字符串对齐。)

标签: c stdin fgets scanf


【解决方案1】:

调试时的技巧总是尝试使用第一个/最后一个索引检查发生了什么。如果您签到:

else if (i >= 3 && i <= 10){
    printf("%c    %s", argChar, argQs[i - 3]);
    for (j = 0; j < ((borderLen - strlen(argQs[i - 3]))-6); j++){
        printf(" ");
    }
    printf("%c\n", argChar);
}

argChar 有 5 个条目,但是当 i=10(条件为 if (i &gt;= 3 &amp;&amp; i &lt;= 10))时,您正试图访问 argQs[i - 3]) 中的 8 个条目。在 C 中你不会得到一个花哨的 IndexOutOfRange 错误,你基本上会访问位于 BASE_ADDR+8 位置的另一个内存注册表。

在 C 中,术语数组和指针几乎可以互换,因为它们都指定了内存块的地址。由于数组基本上是一个 连续 内存块,因此数组的名称是指向第一个元素的指针。示例:array[25] 等价于 *(array + 25)

希望有所帮助。

【讨论】:

  • 哇,这比我想象的要简单得多。我在杂草中走得太远了,认为这是标准输入缓冲区损坏导致的。非常感谢!
猜你喜欢
  • 2011-12-11
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
  • 1970-01-01
相关资源
最近更新 更多