Characters and strings in ANSI C

  • Thread starter AK2
  • Start date
  • Tags
    Strings
In summary: Enter some text"); gets("p"); printf("You entered : %s", *ptr); return 0; } I run it using Dev C++ development ide which uses the GNU C compiler.The code compiled and it didnt run. It gave an error message. This is frustrating. If possible can someone explain gets() function and malloc function because I'm not really understanding it from the book I'm using. I understand the
  • #1
AK2
39
0
I am doing a question (its not home work just an exercise). The following is the question.
Code:
 Write code that allocates space for an 80-character string and then inputs a string from the keyboard and stores it in the allocated space.

This is my code.
Code:
#include <stdio.h>
#include <stdlib.h>
char *ptr, *p;
main()
     {
       ptr = malloc(81);
       p = ptr;
       printf("Enter some text");
       gets("p");
       printf("You entered : %s", *ptr);
       return 0;
     }
I run it using Dev C++ development ide which uses the GNU C compiler.
The code compiled. It didnt run and it gave an error message. This is frustrating. If possible can someone explain gets() function and malloc function because I'm not really understanding it from the book I'm using. I understand the basics like what strings are, characters, ASCII code and the like.
 
Technology news on Phys.org
  • #2
The problem is the line gets("p"). You are telling the computer to read user input into "p", a const char[2] string rather than the character array p.

Get rid of the quotes around p.
 
  • #3
D H said:
The problem is the line gets("p"). You are telling the computer to read user input into "p", a const char[2] string rather than the character array p.

Get rid of the quotes around p.


I did what you told me about removing the double quotations around p. The code compiles but it does not run.
 
  • #4
What exactly do you mean by "does not run?"
 
  • #5
Two problems remain:
  1. printf("Enter some text");
  2. printf("You entered : %s", *ptr);

The second item will cause your program to blow up. I'll leave correcting that line as an exercise to the original poster.

The problem with the first item is a bit more subtle. At this early stage of your programming education, I suggest you add a newline to the end of this prompt: Change this to

printf("Enter some text\n");

The problem here is that printf buffers its output. The default, at least in Unix systems, is to line-buffer the output. Printing one character at a time is very expensive in terms of CPU time. Printing a bunch of characters is still expensive, but not much more expensive than printing one character. In line buffering mode, the system stores output until it gets a newline to print, at which point it prints the entire buffered line.

Suppose you fix the second highlighted line but not the first. The program will run. However, if your system is using line-buffering as the default, the prompt to enter text won't appear until after you enter the text.

There are ways to control the buffering. fflush(FILE *stream) will force whatever output is buffered for the specified output stream to be sent to the output device. setvbuf (FILE *stream, ...) let's you set the buffering for the specified output stream to fully buffered, line buffered, or unbuffered.
 
  • #6
jtbell said:
What exactly do you mean by "does not run?"

I'm sorry for not explaining myself well. It runs but when I enter a line and press enter, there is an error message and the object code doesn't print the line I entered out.

D H said:
Two problems remain:
  1. printf("Enter some text");
  2. printf("You entered : %s", *ptr);

The second item will cause your program to blow up. I'll leave correcting that line as an exercise to the original poster.

The problem with the first item is a bit more subtle. At this early stage of your programming education, I suggest you add a newline to the end of this prompt: Change this to

printf("Enter some text\n");

The problem here is that printf buffers its output. The default, at least in Unix systems, is to line-buffer the output. Printing one character at a time is very expensive in terms of CPU time. Printing a bunch of characters is still expensive, but not much more expensive than printing one character. In line buffering mode, the system stores output until it gets a newline to print, at which point it prints the entire buffered line.

Suppose you fix the second highlighted line but not the first. The program will run. However, if your system is using line-buffering as the default, the prompt to enter text won't appear until after you enter the text.

There are ways to control the buffering. fflush(FILE *stream) will force whatever output is buffered for the specified output stream to be sent to the output device. setvbuf (FILE *stream, ...) let's you set the buffering for the specified output stream to fully buffered, line buffered, or unbuffered.

Thanks a lot for your help. Below is my improved code and it works very well.
Code:
#include <stdio.h>
#include <stdlib.h>
char *ptr, *p;
main()
     {
     ptr = malloc(81 * sizeof(char));
     if (ptr == NULL)
       {
         puts("Memory wasn't allocated");
         exit (1);
       }    
     printf("Enter a line");
     gets(ptr);
     [b]printf("You entered %s\n", ptr);[/b]
     getchar();
     return 0;
     }
\
edit: Even though I removed the * operator from I don't really understand why it is so. I know that *ptr refers to the contents of a variable while ptr refers to the address. can u clear it up for me because I'm confused.
 
Last edited:
  • #7
AK2 said:
edit: Even though I removed the * operator from I don't really understand why it is so. I know that *ptr refers to the contents of a variable while ptr refers to the address. can u clear it up for me because I'm confused.

"ptr" refers to the contents of a variable named "ptr".

"&ptr" refers to the address of a variable named "ptr".

"*ptr" does something slightly different. *ptr assumes that the contents of ptr are a memory address, and returns the value at the memory address stored in the variable "ptr". You can only say "*ptr" if ptr actually is typed as a pointer.

I'm not sure if that was clear, but here's the trick:

When you pass a variable to printf with %s, it is looking for a "string". But a string in C is just an array of characters. It is inconvenient to pass a whole array as an argument, so instead you use a trick. You pass a pointer to the first character in the array. Printf then just looks at every character in the array until it finds a '\0' character (which printf assumes means the end of the character array).

"ptr" is a variable containing a memory address, which points to the first character in the array created by your "malloc" call. So if you pass "ptr" to printf, it gets the memory location of the first character in the array and it is happy. But if you pass "*ptr" to printf, that is not what printf wanted. "*ptr" is the specific character pointed to by the value in "ptr"-- "*ptr" is the first character in the string. So if you pass *ptr to printf, it will just get some garbage that looks like whatever the first letter in the string is. But, printf will think that garbage is a pointer, and it will treat it like a pointer, and it will go to whatever memory address the garbage corresponds to and crash.
 
  • #8
Coin said:
"ptr" refers to the contents of a variable named "ptr".

"&ptr" refers to the address of a variable named "ptr".

"*ptr" does something slightly different. *ptr assumes that the contents of ptr are a memory address, and returns the value at the memory address stored in the variable "ptr". You can only say "*ptr" if ptr actually is typed as a pointer.

I'm not sure if that was clear, but here's the trick:

When you pass a variable to printf with %s, it is looking for a "string". But a string in C is just an array of characters. It is inconvenient to pass a whole array as an argument, so instead you use a trick. You pass a pointer to the first character in the array. Printf then just looks at every character in the array until it finds a '\0' character (which printf assumes means the end of the character array).

"ptr" is a variable containing a memory address, which points to the first character in the array created by your "malloc" call. So if you pass "ptr" to printf, it gets the memory location of the first character in the array and it is happy. But if you pass "*ptr" to printf, that is not what printf wanted. "*ptr" is the specific character pointed to by the value in "ptr"-- "*ptr" is the first character in the string. So if you pass *ptr to printf, it will just get some garbage that looks like whatever the first letter in the string is. But, printf will think that garbage is a pointer, and it will treat it like a pointer, and it will go to whatever memory address the garbage corresponds to and crash.

While reading the unblolded piortion on the post I didnt get it. When I read the bolded part I understood the whole post. Thanks for the clearing it up for me. Sometimes I forget some pointers are variables.
 

Related to Characters and strings in ANSI C

1. What is the difference between characters and strings in ANSI C?

Characters in ANSI C refer to individual letters, symbols, and numbers that are represented by a single byte of data. On the other hand, strings are a sequence of characters that are terminated by a null character '\0'. This means that strings are essentially arrays of characters.

2. How are characters and strings stored in memory in ANSI C?

Characters are stored in memory as a single byte, while strings are stored as an array of characters. The characters in a string are stored consecutively in memory, and the string is terminated by a null character to indicate the end of the string.

3. What is the maximum length of a string in ANSI C?

The maximum length of a string in ANSI C is determined by the size of the array that is used to store the string. The maximum size of an array in ANSI C is determined by the system's memory limitations.

4. How can I access individual characters in a string in ANSI C?

Individual characters in a string can be accessed by using their index position in the string. The first character in a string has an index of 0, and the last character can be accessed by using the strlen() function to determine the length of the string.

5. Can strings be compared in ANSI C?

Yes, strings can be compared in ANSI C using the strcmp() function. This function compares two strings character by character and returns an integer value based on the result of the comparison.

Similar threads

  • Programming and Computer Science
Replies
7
Views
1K
  • Programming and Computer Science
4
Replies
118
Views
6K
  • Programming and Computer Science
Replies
5
Views
1K
  • Programming and Computer Science
Replies
16
Views
5K
  • Programming and Computer Science
Replies
2
Views
1K
  • Programming and Computer Science
Replies
18
Views
2K
  • Programming and Computer Science
Replies
14
Views
2K
  • Programming and Computer Science
Replies
4
Views
760
  • Programming and Computer Science
Replies
5
Views
915
  • Programming and Computer Science
Replies
4
Views
3K
Back
Top