首先,我要感谢大家,无论他们是否知道,他们为我做过的一切。我是第一次长篇潜伏的海报。
我正在开始一个基于C及其几个变体的新类。问题是它假设你至少有过C ++的经验,不幸的是我只花了几个学期的Java和Mips。我现在正努力学习C,没有任何书籍或课程计划。我在第一个月使用Google幸存了下来。但是我今天的问题似乎无法解决这个问题,虽然我知道它是基本的,但我希望能帮助理解我的任务中代码的工作。
教授为我们提供了以下代码:
#include <stdio.h>
#include <string.h>
void encrypt(int offset, char *str) {
int i,l;
l=strlen(str);
printf("\nUnencrypted str = \n%s\n", str);
for(i=0;i<l;i++)
if (str[i]!=32)
str[i] = str[i]+ offset;
printf("\nEncrypted str = \n%s \nlength = %d\n", str, l);
}
void decrypt(int offset, char *str) {
}
void main(void) {
char str[1024];
printf ("Please enter a line of text, max %d characters\n", sizeof(str));
if (fgets(str, sizeof(str), stdin) != NULL)
{
encrypt(5, str); // What is the value of str after calling "encrypt"?
// add your method call here:
}
}
因此,代码中列出了家庭作业的问题,但要明确这不是我所追求的。我想了解这个程序到目前为止是如何运作的。
具体做法是:
为什么要写char str[1024]
if (fgets(str, sizeof(str), stdin) != NULL)
到底在做什么?我有一个不错的主意,但我不知道背后的原因。
3.最后(我希望)
if (str[i]!=32)
str[i] = str[i]+ offset;
为什么我们担心str[i]
不等于32?
我很抱歉,如果要提出这个问题,我真的很想明白这一点。
另外,如果你知道C的任何精彩读物,请告诉我,因为我现在非常担心这个学期的剩余时间。
编辑:
我想非常感谢所有回答我的人。不幸的是,我不是那些立即想要继续提出更多问题来承认你帮助过我的人之一。对于那些我没有直接感谢或回复的人,非常感谢。我现在对30分钟前我感到紧张的一些基本概念有了更为坚定的把握。
答案 0 :(得分:2)
char str[1024]
因为C没有任何字符串概念,只有char
的数组由NUL又名为0终止。它没有任何“弹性”容器概念。没有明确地实现自己。因此,如果您想要读取一串输入而不需要编写大量自己的输入处理,那么您可以猜测某个最大长度(在这种情况下为1024),并提前为此腾出空间。fgets
读取一个字符串(当你在C中说“string”时,意味着“char
数组以0结尾,如上所述。)你传入str
这是指向存储开始的指针和sizeof(str)
,它在编译时被评估为str
占用的字节数。在这种情况下,它意味着1024
,具有它的优势如果您更改char str
行,则会跟踪更改。该参数阻止fgets
写入超出str
的分配空间。请记住,它不是一个有弹性的字符串。str[i] != ' '
答案 1 :(得分:2)
一个很好的开始是Kernighan + Ritchie的书, The C Programming Language 。
亚马逊:here
答案 2 :(得分:0)
str
是一个1024 char
s PS。 “gets()和fgets()成功返回s,错误时返回NULL或文件结束时没有读取任何字符。”
答案 3 :(得分:0)
char str[1024];
将str
声明为char
的1024个元素数组。
fgets(str, sizeof (str), stdin)
从sizeof (str)
(标准输入,基本上是您的控制台)读取最多stdin
(1024)个字符,并将这些字符存储到str
。如果在读取过程中出现错误,fgets
将返回NULL,所以
if (fgets(std, sizeof(str), stdin) != NULL)
{
encrypt(...);
...
}
只有在我们成功读取输入字符串时,才会执行if
语句的主体。
32
是空格(' '
)字符的ASCII码;无论出于何种原因,加密算法都会在字符串中保留空格字符。
答案 4 :(得分:0)
在Java中,您必须new
所有数组,例如char[] arr = new char[1024]
。在C(和C ++)中,您可以选择像Java一样动态分配数组(在C中使用malloc
,在C ++中使用new []
),或者使用固定大小静态分配数组({{ 1}}你看到了。)
在C中,因为需要使用char str[1024]
和malloc
手动管理所有内存,所以静态分配的缓冲区可以节省一些麻烦,因为它们会在函数退出时自动释放。在Java中,您很少处理内存分配,因为运行时会自动垃圾收集未使用的对象。
在Java中,你有free
,它包含一个String
数组。在C中,您只有char数组,通常表示为char
数组或指向第一个字符(char
)的指针。另请注意,Java char *
处理Unicode时为16位(2字节)宽; C char
的大小只有8位(1字节)。
最后,请注意,在C中,所有字符串都以空字节char
终止。因此,字符串必须足够大以容纳内容和终止空字节 - 无法计算空字节可能导致缓冲区溢出。
在Java中,您可以使用'\0'
从文件或用户输入中读取一行文本。在C中,您使用readLine
。但是,在Java中,运行时将动态分配一个足以容纳输入行的字符串(无论该行多长);在C中,由于缓冲区通常由程序员分配,因此该函数只能读取缓冲区允许的字符数(读取缓冲区末尾的字符称为缓冲区溢出,这是常见的原因)安全漏洞)。
fgets
因此需要三个参数:要读入的缓冲区,缓冲区的大小以及要读取的文件(此处fgets
,即控制台)。
C中的字符串只是ASCII字符的序列。因此,只有当字符不是32 - 空格字符时,代码才会加密字符(通过添加此“偏移”)。结果是所有非空间都将被转换为乱码,使空间保持不变。