【问题标题】:C Program 'stuck' After Accepting Input接受输入后 C 程序“卡住”
【发布时间】:2018-03-02 08:15:13
【问题描述】:

抱歉标题的措辞,我想不出更好的方式来表达我的问题。在我的代码中,我为我调用间隔的结构获取 n 组输入。如果用户只想输入 1 个结构,那么程序接受输入并打印就可以了。但是,任何大于 1 的值都将接受所有输入,但在结构中存储整数的最后一个输入之后,它将变为“卡住”,光标将向下移动一行,就好像它正在等待输入一样。除非无论您输入什么程序都没有进展。我需要了解是什么阻止了我的程序进行。感谢您的所有帮助。

错误(我假设)在调用函数 takeInput 时主要出现。

我在 Linux 机器上使用 gcc 编译。下面是代码。

#include <stdio.h>

typedef struct interval{
    int num_left, denum_left;
    int num_right, denum_right;
    int left_state, right_state;
}interval;

interval combine(interval x, interval y);
int combineCheck(interval x, interval y);
int valueCheck(interval x, interval y);
void mergeSort(interval x[], int l, int r);
void merge(interval x[], int l, int m, int r);
interval takeInput();

int main(){
    int response, i;
    char d;
    printf("Enter the number of intervals to input: ");
    scanf("%d", &response);
    interval data[response];

    for(i = 0; i < response; i++){
        data[i] = takeInput();
    }
    printf("%d/%d   %d/%d", data[0].num_left, data[0].denum_left, data[0].num_right, data[0].denum_right);

    mergeSort(data, 0, response-1);

    printf("%d/%d   %d/%d", data[0].num_left, data[0].denum_left, data[0].num_right, data[0].denum_right);
}

interval takeInput(){
    interval temp;
    printf("Enter left numerator: ");
    scanf("%d", &temp.num_left);
    printf("Enter left denominator: ");
    scanf("%d", &temp.denum_left);
    printf("Enter right numerator: ");
    scanf("%d", &temp.num_right);
    printf("Enter right denominator: ");
    scanf("%d", &temp.denum_right);
    printf("\n");

    if(temp.num_left < 0){
        temp.num_left = temp.num_left*-1;
        temp.left_state = -1;}
    else{
        temp.left_state = 0;}

    if(temp.num_right < 0){
        temp.num_right = temp.num_right*-1;
        temp.right_state = -1;}
    else{
        temp.right_state = 0;}
    printf("Testing Shit");
    return temp;
}

int combineCheck(interval x, interval y){
    int left, right;
    left = x.num_right * y.denum_left;          //used to find relationship between 2 fractions
    right = y.num_left * x.denum_right;

    if(left == right && (x.right_state + x.left_state) == 0){
        return 1;
    }
    else if(left > right){
        return 1;
    }
    return 0;
}

interval combine(interval x, interval y){
    int left, right;                        //used to check if one interval is all encompassing
    left = x.num_right * y.denum_right;
    right = x.denum_right * y.num_right;

    interval temp;
    temp.num_left = x.num_left;
    temp.denum_left = x.denum_left;
    temp.left_state; 
    if(left > right){
        temp.num_right = x.num_right;
        temp.denum_right = x.denum_right;
        temp.right_state = x.right_state;
        return temp;
    }
    temp.num_right = y.num_right;
    temp.denum_right = y.denum_right;
    temp.right_state = y.right_state;
    return temp;
}

int valueCheck(interval x, interval y){
    int first, second;                  //used to check values
    first = x.num_left * y.denum_left;
    second = y.num_left * x.denum_left;
    if(first > second){
        return 1;
    }
    return -1;
}

void mergeSort(interval x[], int l, int r){
    if(l < r){
        int m = l + (r-1)/2;

        mergeSort(x, l, m);
        mergeSort(x, m+1, r);
        merge(x, l, m, r);
    }
}

void merge(interval arr[], int l, int m, int r){
    int i, j, k;
    int n1 = m-l +1;
    int n2 = r-m;

    interval L[n1], R[n2];

    for(i = 0; i < n1; i++)
        L[i] = arr[l + i];
    for(j = 0; j < n2; j++)
        R[j] = arr[m + 1 + j];
    j = 0;
    i = 0;
    k = l;
    while(i < n1 && j < n2){
        if(valueCheck(L[i], R[j]) == -1){
            arr[k] = L[i];
        }
        else{
            arr[k] = R[j];
            j++;
        }
    }

    while(i < n1){
        arr[k] = L[i];
        i++;
        k++;
    }

    while(j < n2){
        arr[k] = R[j];
        j++;
        k++;
    }
}

这是输出的样子

【问题讨论】:

  • 我没有看过你的代码,但你所描述的看起来像一个无限循环。检查 for 和 while 循环中的条件值(在循环中打印它们)。尼古拉斯 :)
  • 编译所有警告和调试信息 (gcc -Wall -Wextra -g) 并使用调试器 gdb

标签: c sorting input


【解决方案1】:

您的合并排序例程中有一些问题:

k = l;
while(i < n1 && j < n2){
    if(valueCheck(L[i], R[j]) == -1){
        arr[k] = L[i];
    }
    else{
        arr[k] = R[j];
        j++;
    }
}

在分配给 arr 后,您不会增加 i。由于 i 永远不会改变,因此您的 while 循环永远不会终止。在第一个 if 条件中添加i++,它会起作用。另请参阅 MondKin 提出的观点,这也是您代码中的一个非常严重的问题。

【讨论】:

  • 非常感谢您的帮助。当我疲倦时,我犯的愚蠢错误真是令人惊讶。如果我刚刚清除缓冲区,我会知道它与我的算法有关,而不是其他想法。
  • 没问题!正如我们所说,只有无所事事的人才不会犯错! :-)
【解决方案2】:

检查您的合并排序算法我看到了:

int m = l + (r-1)/2;

我想你的意思是:

int m = l + (r-l)/2;

因为你想要的是中间索引。

【讨论】:

  • 非常感谢您的帮助,让我在疲倦时想念的东西真是太棒了。
【解决方案3】:

正如其他人指出的那样,存在无限循环问题。您不能在调试打印中指出这一点,因为它可能不会在调用它们时刷新。您可以在调试打印中添加换行符,以查看您的程序卡在哪里。

【讨论】:

    【解决方案4】:

    我认为中间索引m不正确。

    改变这个:

    int m = l + (r-1)/2;
    

    到这里:

    int m = (l + r) / 2;
    

    【讨论】:

    • 或者m = (l+r)/2也许
    猜你喜欢
    • 2014-08-19
    • 2021-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 2023-03-07
    • 2021-07-09
    • 2021-02-25
    相关资源
    最近更新 更多