I made a simple experiment. Tried to answer a 1st year C question. The trick is to pay attention to the requirements and avoid common pitfalls. Also, there is no need for full blown code to answer the question, just two lines of code.
Can ChatGPT help? Some conclusions, after the chat listing.
In light gray are my inputs and in green are the ChatGPT answers. Of course, its output is formatted nicer than here!
The discussion
Hi! I have this code snippet in C, that should read a string into the 5th location of an array of strings:
char string[100];
scanf("%s", string[5]);
Can you tell me please if this is correct and some ways to correct it?
No, this code is incorrect. The code should be:
char string[100];
char *ptr = string + 4;
scanf("%s", ptr);
In this case, ptr
is a pointer that points to the 5th location of the string
array. The scanf
function will read the string into the memory location pointed by ptr
.
Are you sure that this code obeys the “array of strings” requirement?
No, this code does not obey the “array of strings” requirement. The string
array is declared as an array of char
, not an array of strings. To make it an array of strings, the declaration should be:
char string[5][100];
scanf("%s", string[4]);
In this case, string
is now an array of 5 strings, each with a maximum length of 100 characters. The scanf
function will read the string into the 5th location of the string
array.
Can you make it so I have 100 strings, but each string can have different sizes?
Yes, you can have 100 strings with different sizes by using a 2D dynamic array of char. Here’s an example:
char **strings;
strings = (char **)malloc(100 * sizeof(char *));
int i;
for (i = 0; i < 100; i++) {
int size;
printf("Enter the size of string %d: ", i + 1);
scanf("%d", &size);
strings[i] = (char *)malloc((size + 1) * sizeof(char));
printf("Enter string %d: ", i + 1);
scanf("%s", strings[i]);
}
In this code, strings
is a 2D dynamic array of char
, where each row is a pointer to a string with a different size. The malloc
function is used to dynamically allocate memory for each string. The size of each string is entered by the user, and the string is read into the corresponding location in the strings
array using scanf
.
Ok! So if the requirement is to have only declaration and keyboard reading instructions, this will do?
char **strings;
scanf("%s", strings[i]);
No, this code is incorrect. The strings
variable has not been properly declared or initialized. The code should be:
char **strings;
strings = (char **)malloc(100 * sizeof(char *));
int i;
for (i = 0; i < 100; i++) {
int size;
printf("Enter the size of string %d: ", i + 1);
scanf("%d", &size);
strings[i] = (char *)malloc((size + 1) * sizeof(char));
printf("Enter string %d: ", i + 1);
scanf("%s", strings[i]);
}
Here, strings
is declared as a pointer to a pointer to char
, which is the correct syntax for a 2D dynamic array of char
. The memory for the strings
array is then dynamically allocated using the malloc
function. The size of each string is entered by the user, and the string is read into the corresponding location in the strings
array using scanf
.
Ok, I understand.
Great! I’m glad I could help. If you have any more questions, feel free to ask.
However, one of my colleagues are whispering that this code might deliver the whole network in the hands of an n00b hacker. Is there a security issue with this code?
Yes, there is a security issue with this code. The scanf
function does not check the size of the input and can lead to a buffer overflow vulnerability. If a user enters a string that is larger than the allocated memory for a string, it can overwrite adjacent memory locations and potentially lead to a program crash or even a security breach.
To mitigate this issue, you can use the fgets
function instead of scanf
to read the strings. The fgets
function takes a maximum length as an argument, ensuring that the input cannot overflow the buffer. Here’s an example:
char **strings;
strings = (char **)malloc(100 * sizeof(char *));
int i;
for (i = 0; i < 100; i++) {
int size;
printf("Enter the size of string %d: ", i + 1);
scanf("%d", &size);
strings[i] = (char *)malloc((size + 1) * sizeof(char));
printf("Enter string %d: ", i + 1);
fgets(strings[i], size + 1, stdin);
}
In this code, fgets
is used to read the strings instead of scanf
. The fgets function takes a maximum length as an argument, ensuring that the input cannot overflow the buffer.
Ok! Thank you!
You’re welcome! I’m glad I could help. If you have any more questions, feel free to ask.
Conclusions?
- No attention to details. Needed to point the “array of strings” requirement before figuring it out
- Answers are brittle. Want a snippet? No, it wants to splill the whole code, no matter the input
scanf
? SRSLY? If it has the info of security issues, why outputting the wrong answer in the 1st place? Answer: Because this is Machine Learning, also known as Pattern Recognition. It outputs the most frequent text that is after “read from keyboard in C”. Of course, with nice grammatical syntax. However, THERE IS ZERO UNDERSTANDING or reasoning.- Excellent tool to explain things. IMHO this is the killer app for ChatGPT. Put it to explain why a certain line of code is present and what it does. Chat approach helps navigating towards things that need explanations. It will easily aggregate answers from different sources and pack them nicely.