我正在尝试调试我编写的这个程序,但我得到的只是垃圾值。
/*
* 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] + °ree;
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", °ree, "\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
请告诉我这个程序出了什么问题。
答案 0 :(得分:3)
您的代码包含一些错误的行为。
我想也许你是来自另一种语言并试图学习C?
好吧,让我们看看代码中出现了哪些错误。
char rotateArray(char str[], int degree, int length) {
char temp[length];
for(int i=0; i < length +1; i++)
{
str[i] = str[i]+ °ree;
str[i] = temp[i];
//printf ("%c", str[i]);
}
return &str;
}
我的猜测是你正在尝试逐个旋转(移动角色)并将其存储到temp
字符串数组中。您实际上不需要将新的旋转值存储到新的temp
中,因为str
数组已在此处str[i] = str[i]+ °ree
进行了修改。原因是在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; */
}
在正文中,几乎每个printf
和scanf
都在后面插入了\n
。我再次猜测这种编码风格是否受到另一种编程语言的影响? :)
实际上,在C中,除非在格式字符串中放置了说明符,否则不必将\n
作为新参数。因此,您可以完全删除, "\n"
。
/* printf("Enter the value of degree: ", "\n"); */
printf("Enter the value of degree: ");
/* scanf("%d",°ree, "\n"); */
scanf("%d",°ree);
/* 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程序员的野兽。请查看更多讨论这些问题的资源。
最后,在你的主体结束时,
printf("%s\n", rotateArray);
这有点胡说八道,因为您正在尝试打印函数名称。好吧,我想再一次也许你认为它会打印函数的返回值,对吗?
实际上,从我之前在顶部告诉你的,作为str
参数传递给函数的任何字符串数组都有点像引用,所以当你在里面修改str
时rotateArray
身体它也会“影响”主要功能的价值。
所以代替那个错误的代码,你可以把它改成这样,
/* 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",°ree, "\n"); */
scanf("%d",°ree);
/* 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]+ °ree; //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)
编码功能有问题:
循环索引应该从0
到len - 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);
的第二个参数应为50
或sizeof(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", °ree) != 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;
}