来自硬件工程师的C程序,编码背景很少

时间:2017-08-18 05:46:44

标签: c

我正在尝试调试我编写的这个程序,但我得到的只是垃圾值。

/*
 *  Assignment.c
 *
 *  Created on: 18-Aug-2017
 *  Author: sumeetpatil
 */

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

char rotateArray(char str[], int degree, int length) {
    char temp[length];
    for (int i = 0; i < length + 1; i++) {
        str[i] = str[i] +  &degree;
        str[i] = temp[i];
        //printf ("%c", str[i]);
    }
    return &str;
}

int main() {
    int length;
    int degree;
    char encryptArr[50];

    printf("Enter the value of degree: ", "\n");

    scanf("%d", &degree, "\n");

    printf("Enter the string array you want to encrypt: ", "\n");

    fgets(encryptArr, 100, stdin);

    scanf("%[^\n]%*c", &encryptArr);

    length = strlen(encryptArr);

    printf("The character string is: %s\n", encryptArr, "\n");

    printf("The size of character array is %u\n", length);

    rotateArray(encryptArr, degree, length);

    printf("%s\n", rotateArray);
}

我的输出如下:

Enter the value of degree: 1
Enter the string array you want to encrypt: youmadbro
The character string is: youmadbro
The size of character array is 9
UH��H��@H�a

请告诉我这个程序出了什么问题。

4 个答案:

答案 0 :(得分:3)

您的代码包含一些错误的行为。

我想也许你是来自另一种语言并试图学习C?

好吧,让我们看看代码中出现了哪些错误。

1

char rotateArray(char str[], int degree, int length) {

    char temp[length];
    for(int i=0; i < length +1; i++)
    {
        str[i] = str[i]+ &degree;
        str[i] = temp[i];
        //printf ("%c", str[i]);
        }
    return &str;
}

我的猜测是你正在尝试逐个旋转(移动角色)并将其存储到temp字符串数组中。您实际上不需要将新的旋转值存储到新的temp中,因为str数组已在此处str[i] = str[i]+ &degree进行了修改。原因是在C中,一个数组被传递给类似的引用,所以你可以修改它,它仍然会“影响”它之外的str值。

因此我们可以完全删除temp数组。

/* char rotateArray(char str[], int degree, int length) { */
void rotateArray(char str[], int degree, int length) {

    /* char temp[length]; */

    for(int i=0; i < length +1; i++)
    {
        str[i] = str[i]+ degree;
        /* str[i] = temp[i]; */
        //printf ("%c", str[i]);
    }
    /* return &str; */
}

2

在正文中,几乎每个printfscanf都在后面插入了\n。我再次猜测这种编码风格是否受到另一种编程语言的影响? :)

实际上,在C中,除非在格式字符串中放置了说明符,否则不必将\n作为新参数。因此,您可以完全删除, "\n"

/* printf("Enter the value of degree: ", "\n"); */
printf("Enter the value of degree: ");

/* scanf("%d",&degree, "\n"); */
scanf("%d",&degree);

/* printf("Enter the string array you want to encrypt: ", "\n"); */
printf("Enter the string array you want to encrypt: ");

/* printf("The character string is: %s\n", encryptArr, "\n"); */
printf("The character string is: %s\n", encryptArr);

printf&amp; scanf有点像新C程序员的野兽。请查看更多讨论这些问题的资源。

3

最后,在你的主体结束时,

printf("%s\n", rotateArray);

这有点胡说八道,因为您正在尝试打印函数名称。好吧,我想再一次也许你认为它会打印函数的返回值,对吗?

实际上,从我之前在顶部告诉你的,作为str参数传递给函数的任何字符串数组都有点像引用,所以当你在里面修改strrotateArray身体它也会“影响”主要功能的价值。

所以代替那个错误的代码,你可以把它改成这样,

/* printf("%s\n", rotateArray); */
printf("%s\n", encryptArr);

因此,最终修改后的代码将是:

/*
 *  Assignment.c
 *
 *  Created on: 18-Aug-2017
 *  Author: sumeetpatil
 */

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

/* char rotateArray(char str[], int degree, int length) { */
void rotateArray(char str[], int degree, int length) {

    /* char temp[length]; */

    for(int i=0; i < length +1; i++)
    {
        str[i] = str[i]+ degree;
        /* str[i] = temp[i]; */
        //printf ("%c", str[i]);
    }
    /* return &str; */
}

int main(){

    int length;
    int degree;
    char encryptArr[50];

    /* printf("Enter the value of degree: ", "\n"); */
    printf("Enter the value of degree: ");
    fflush(stdout);

    /* scanf("%d",&degree, "\n"); */
    scanf("%d",&degree);

    /* printf("Enter the string array you want to encrypt: ", "\n"); */
    printf("Enter the string array you want to encrypt: ");
    fflush(stdout);

    fgets(encryptArr, 100, stdin);

    scanf ("%[^\n]%*c", &encryptArr);

    length = strlen(encryptArr);

    /* printf("The character string is: %s\n", encryptArr, "\n"); */
    printf("The character string is: %s\n", encryptArr);

    printf("The size of character array is %u\n", length);

    rotateArray(encryptArr, degree, length);

    /* printf("%s\n", rotateArray); */
    printf("%s\n", encryptArr);

}

加成

你想在这里实现的是Caesar cipher

您的实现错误,因为它无法正确处理“字母溢出”。我的意思是当您的代码超过z时,它不会再次将自身轮换到a。有许多方法可以通过使用余数运算符%或使用if-else语句来检查字母表是否溢出来实现此目的。

尝试查看示例here

答案 1 :(得分:0)

让我们从不正常的事情开始。

scanf ("%[^\n]%*c", &encryptArr); //Wrong
scanf ("%[^\n]%*c", &encryptArr[0]); //OK
scanf ("%[^\n]%*c", encryptArr); //OK

现在你的旋转功能。

char rotateArray(char str[], int degree, int length) {
    char temp[length]; //Declared on stack, values are not known, UB
    for(int i=0; i < length + 1; i++) { //Why +1? Forces UB in later stage
        str[i] = str[i]+ &degree; //Degree is variable on stack, adding & is just getting address from stack
        str[i] = temp[i]; //Assigning temp value with undefined value
        //printf ("%c", str[i]); //Printing undefined value
        }
    return &str; //You should get at least warning here.
    return str[0]; //Better
}

现在这是通用的。当您根据输入告诉我们所需的输出时,我将能够告诉您更多信息。

printf("%s\n", rotateArray);

您不能只将函数名称打印为字符串。这是C中未定义的行为。

答案 2 :(得分:0)

编码功能有问题:

  • 循环索引应该从0len - 1不等,因此测试应该是:

    for (int i = 0; i < length; i++) { ...
    
  • 将字符值移动degree必须更加小心,分别处理小写和大写字符,并使用模数计算进行循环排列。

  • 要使用degree的值,您不需要&地址运算符。

  • 字符串已就地修改,您不需要临时数组。

以下是更正后的版本:

char *rotateArray(char *str, int degree, int length) {
    for (int i = 0; i < length; i++) {
        char c = str[i];
        if (c >= 'a' && c <= 'z') {
            str[i] = 'a' + (c - 'a' + degree) % 26;
        } else
        if (c >= 'A' && c <= 'Z') {
            str[i] = 'A' + (c - 'A' + degree) % 26;
        }
    }
    return str;
}

main()功能也存在问题:

  • fgets()scanf()是两种不同的方式来阅读字符串,只需使用一种。

  • fgets(encryptArr, 100, stdin);的第二个参数应为50sizeof(encryptArr),以告诉fgets()目标数组的大小并防止缓冲区溢出。

  • 您向"\n"scanf()传递了被忽略的额外printf()个参数。启用编译器警告(-Wall -Wextra)并研究消息。

  • 函数rotateArray()修改了encryptArr,您应该将encryptArr传递给printf()而不是函数名。

以下是更正后的版本:

int main(void) {
    int length;
    int degree;
    char encryptArr[50];

    printf("Enter the value of degree: ");
    if (scanf("%d", &degree) != 1)
        return 1;

    printf("Enter the string array you want to encrypt: ");
    if (!fgets(encryptArr, sizeof(encryptArr), stdin))
        return 1;

    length = strlen(encryptArr);
    printf("The character string is: %s\n", encryptArr);
    printf("The length of character string is %d\n", length);

    rotateArray(encryptArr, degree, length);
    printf("%s\n", encryptArr);

    return 0;
}

最后,您将<stdio.h>包括两次。虽然它不会导致问题,但您应该只包含一次头文件,并且只包含那些:

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

答案 3 :(得分:0)

使用此:

char *rotateArray(char *str, int degree, int length) {
    for (int i = 0; i < length; i++) {
        char c = str[i];
        if (c >= 'a' && c <= 'z') {
            str[i] = 'a' + (c - 'a' + degree) % 26;
        } else
        if (c >= 'A' && c <= 'Z') {
            str[i] = 'A' + (c - 'A' + degree) % 26;
        }
    }
    return str;
}