For working professionals
For fresh graduates
More
5. Array in C
13. Boolean in C
18. Operators in C
33. Comments in C
38. Constants in C
41. Data Types in C
49. Double In C
58. For Loop in C
60. Functions in C
70. Identifiers in C
81. Linked list in C
83. Macros in C
86. Nested Loop in C
97. Pseudo-Code In C
100. Recursion in C
103. Square Root in C
104. Stack in C
106. Static function in C
107. Stdio.h in C
108. Storage Classes in C
109. strcat() in C
110. Strcmp in C
111. Strcpy in C
114. String Length in C
115. String Pointer in C
116. strlen() in C
117. Structures in C
119. Switch Case in C
120. C Ternary Operator
121. Tokens in C
125. Type Casting in C
126. Types of Error in C
127. Unary Operator in C
128. Use of C Language
Working with string input and output in C can be a bit tricky, especially when spaces come into play. If you've ever tried using scanf() to input a sentence or a name with spaces, you may have noticed that it stops reading at the first space.
This is where things can get confusing for beginners, how do you handle strings with spaces? Luckily, C provides a few ways to manage this, but knowing the right tools to use, like fgets() and the scanset in scanf(), can make all the difference. That’s why this concept is also a part of top-tier software development courses.
In this blog, we’ll take a deep dive into string input and output in C. We'll explore how to take input both with and without spaces, how to safely handle strings with functions like scanf() and fgets(), and how to output strings properly. By the end, you’ll not only understand how to manage strings more effectively but also be aware of the potential pitfalls, like buffer overflows and unwanted newline characters, and how to avoid them.
Unlock your potential by enrolling in the first-of-its-kind Generative AI Doctorate program from Golden Gate University!
In C, strings are not a built-in data type. Instead, a string is implemented as an array of characters, terminated by a null character (`'\0'`). Input and output of strings in C refer to reading a sequence of characters into such an array and then displaying them using standard output functions.
This is the process of capturing characters typed by the user and storing them in a character array. The string is usually read from standard input (keyboard).
This involves displaying the contents of a character array to the standard output (screen). Functions like `printf()` and `puts()` are commonly used for this purpose.
Example
#include <stdio.h>
int main() {
char fullName[50]; // Declare a character array to hold the input string
printf("Enter your full name: ");
fgets(fullName, sizeof(fullName), stdin); // Reads a line including spaces
printf("You entered: %s", fullName); // Outputs the stored string
return 0;
}
Expected Output
Enter your full name: Ananya Sharma
You entered: Ananya Sharma
Explanation
This example illustrates both string input (via `fgets`) and string output (via `printf`) using a real-world scenario.
In C, if you need to take input of a string that doesn't contain spaces, you can use the `scanf()` function with the `%s` format specifier. This function reads a string of characters until it encounters the first whitespace (such as a space, tab, or newline). It is ideal for scenarios where you expect a single word or identifier.
Before you get into the depth of it, you should understand about the input and output function in C.
Syntax:
scanf("%s", str);
Example:
#include <stdio.h>
int main() {
char name[30]; // Declare an array to store the input string
printf("Enter your name: ");
scanf("%s", name); // Reads a single word (no spaces)
printf("Hello, %s!\n", name); // Outputs the input string
return 0;
}
Expected Output
Enter your name: Sam
Hello, Sam!
Explanation
The `scanf()` function is used in C for reading input from the user, and it can handle various data types, including strings, integers, and floating-point numbers. When reading strings, `scanf()` uses a format specifier to determine how to interpret the input.
scanf("format_specifier", argument1, argument2, ...);
#include <stdio.h>
int main() {
char city[50]; // Declare a character array to hold the input
printf("Enter your city: ");
scanf("%s", city); // Reads a single word into 'city'
printf("City: %s\n", city); // Outputs the string entered
return 0;
}
Expected Output
Enter your city: NewYork
City: NewYork
Explanation
Also explore Doctor of Business Administration from Rushford Business School
Here are some of the common format specifiers:
Furthermore, for in-depth details, explore our blog on format specifiers in C.
The `scanf()` function is commonly used to read input in C. It works by examining the input stream and matching the input with the format specifiers provided in its argument. Here’s a deeper look at how `scanf()` processes input when dealing with strings and other data types.
Here a step-by-step explanation:
1. Format Specifiers: When `scanf()` is called, it processes the format string to understand what kind of data is expected. For strings, it uses `%s`, which tells `scanf()` to expect a sequence of characters.
2. Input Buffer: The input is read from the input buffer (usually the keyboard). The function processes the input one character at a time, comparing it to the format specifiers.
3. Whitespace Handling: When using `%s` to read strings, `scanf()` skips leading whitespace characters like spaces or newlines. It then reads characters until it encounters the first whitespace character (space, tab, or newline).
4. Termination: When `scanf()` reaches a whitespace or end of the valid input, it:
Example
#include <stdio.h>
int main() {
char firstName[30]; // Declare an array to store the string input
printf("Enter your first name: ");
scanf("%s", firstName); // Reads input until a space or newline
printf("First Name: %s\n", firstName); // Prints the input string
return 0;
}
Expected Output
Enter your first name: Rahul
First Name: Rahul
Explanation
The `scanf()` function is a powerful and efficient way to read input in C. Despite some limitations, it offers several advantages, especially when dealing with simple inputs and scenarios where performance is a concern.
Here are some of the main benefits of using `scanf()`:
1. Simple and Straightforward Syntax
The syntax of `scanf()` is simple, making it easy to understand and implement for basic input operations. For example, reading a string with `%s` or an integer with `%d` requires minimal code and setup.
2. No Need for Explicit Buffer Management (For Basic Cases)
`scanf()` automatically manages memory allocation when reading simple types like integers or single-word strings. This means you don’t need to worry about setting up buffers manually, as long as the input is small and within the array's capacity.
3. Efficient for Single Data Type Inputs
For reading a single value (like an integer or a float), `scanf()` is extremely efficient. It processes the input stream in a straightforward manner, reducing overhead compared to using other methods like `fgets()` and `sscanf()`.
4. Format Flexibility
`scanf()` supports various format specifiers for different data types, including strings, integers, floats, and characters. This makes it versatile for a range of input scenarios in C.
5. Works Well for Well-Defined Inputs
If you know the exact format of the input ahead of time (e.g., reading an integer or a single word), `scanf()` is quick and effective. It saves time by directly parsing the input according to the given format.
Example
#include <stdio.h>
int main() {
int age; // Declare an integer variable to hold input
printf("Enter your age: ");
scanf("%d", &age); // Reads an integer from user input
printf("You are %d years old.\n", age); // Outputs the value entered
return 0;
}
Expected Output
Enter your age: 25
You are 25 years old.
Explanation
While `scanf()` is widely used in C for reading input, it has several limitations and drawbacks that can lead to unexpected behaviors or issues, especially when handling more complex input scenarios. Below are some of the key disadvantages of using `scanf()`:
1. Inability to Handle Whitespace in Strings
When using `%s` to read a string, `scanf()` stops reading at the first whitespace character (space, tab, or newline). This means that if a user enters a multi-word string, only the first word will be captured, and the rest will be discarded.
For example: if a user enters "Rahul", `scanf()` will only capture "Rahul", leaving "Doe" behind.
2. No Input Validation
`scanf()` doesn't provide any built-in input validation. If the user enters data that doesn't match the expected format (e.g., entering a string when expecting an integer), `scanf()` may fail or produce unpredictable results, and the input buffer may remain in an inconsistent state.
3. Leaves Unwanted Characters in the Input Buffer
After reading input, `scanf()` often leaves unwanted characters (such as newline or space) in the input buffer. This can affect subsequent input operations. For example, if `scanf()` reads an integer and leaves the newline character in the buffer, the next `scanf()` call may immediately read that newline and behave unexpectedly.
4. Risk of Buffer Overflow
`scanf()` does not automatically limit the size of the input, and if the user enters more characters than the allocated buffer can handle, it can lead to a buffer overflow. This can corrupt memory and lead to unpredictable behavior or even program crashes.
Example: If a character array is allocated with 10 spaces but the user enters a string of 50 characters, `scanf()` will attempt to store it in the array, potentially causing a crash.
5. Can Lead to Undefined Behavior
If `scanf()` is not used carefully, especially when working with format specifiers, it can lead to undefined behavior. For instance, using mismatched format specifiers for the type of data being inputted can cause memory corruption or incorrect behavior.
Here’s an example of buffer overflow issue:
#include <stdio.h>
int main() {
char name[10]; // Allocate a small buffer for the string
printf("Enter your name: ");
scanf("%s", name); // No limit on input size
printf("Hello, %s!\n", name);
return 0;
}
Expected Output
Enter your name: RahulSharmaLongName
Hello, RahulSharmaLongName!
Explanation
In this example, the buffer `name` is only allocated 10 characters, but the user enters more than 10 characters. `scanf()` will try to store all the characters, causing a buffer overflow and potentially corrupting memory, leading to undefined behavior.
By default, `scanf("%s", ...)` does not handle spaces in strings, meaning it reads input only until it encounters the first whitespace (space, tab, or newline). However, if you need to read a string that includes spaces (such as a full name or address), there are alternative methods to capture the entire string, including spaces.
Also pursue Post Graduate in Product management Course from Duke CE
One of the most common and safe ways to take input of a string with spaces is by using the `fgets()` function. Unlike `scanf()`, `fgets()` allows the user to input multiple words with spaces, and it reads input until a newline is encountered, or the specified buffer size is reached.
Syntax for `fgets()`
fgets(str, size, stdin);
In the syntax:
Example
#include <stdio.h>
int main() {
char fullName[50]; // Declare a buffer to store the input string
printf("Enter your full name: ");
fgets(fullName, sizeof(fullName), stdin); // Reads input including spaces
printf("Full Name: %s", fullName); // Outputs the string entered
return 0;
}
Expected Output
Enter your full name: Rahul
Full Name: Rahul
Explanation
In C programming, both `gets()` and `fgets()` are used to read strings from the user. However, they have significant differences, and understanding these differences is crucial for writing safe and efficient code.
`gets()` is an older function used to read a string of characters from the user until a newline character (`'\n'`) is encountered. However, it has been deprecated in recent versions of C due to serious safety concerns.
Here are some of the key issues:
1. No Bound Checking: `gets()` does not perform any checks to ensure that the input does not exceed the size of the buffer allocated for the string. This leads to the risk of buffer overflow, which can overwrite memory and cause undefined behavior, crashes, or vulnerabilities in the program.
2. Potential for Security Vulnerabilities: Due to its lack of bounds checking, `gets()` is considered unsafe. Using `gets()` can allow malicious users to provide more input than expected, potentially compromising the program's security.
In contrast, `fgets()` is a safer and more reliable function for reading strings, as it includes bounds checking and allows you to specify the maximum number of characters to read.
Here are some of the advantages:
1. Bounds Checking: `fgets()` requires you to specify the maximum number of characters to read, which helps avoid buffer overflow.
2. Retains Newline Character: Unlike `gets()`, `fgets()` retains the newline character (`'\n'`) at the end of the input if it fits within the buffer, which can be useful for certain applications but may need to be manually removed if not desired.
3. Safer: `fgets()` is a much safer alternative to `gets()` because it prevents the possibility of overwriting memory beyond the bounds of the buffer.
#include <stdio.h>
int main() {
char name[20]; // Allocate a small buffer for the string
printf("Enter your name: ");
gets(name); // Unsafe: no bounds checking
printf("Hello, %s!\n", name);
return 0;
}
Expected Output (But Dangerous)
Enter your name: Vikram
Hello, Vikram
This code works as expected, but there’s no guarantee that the input will fit within the `name` buffer, and entering more than 20 characters would cause a buffer overflow.
#include <stdio.h>
int main() {
char name[20]; // Allocate a small buffer for the string
printf("Enter your name: ");
fgets(name, sizeof(name), stdin); // Safe: bounds checking
printf("Hello, %s!\n", name);
return 0;
}
Expected Output
Enter your name: Ram
Hello, Ram
In this case, `fgets()` will stop reading once the buffer size is reached, making it much safer than `gets()`.
The `scanf()` function in C offers a powerful feature known as scanset (denoted as `[% ]`), which allows you to specify a set of characters that you want to read from the input. This is particularly useful when you need to read strings with specific characters or delimiters and is more flexible than just using `%s` for basic string input.
A scanset in `scanf()` allows you to specify a set of acceptable characters that can be read. For example, if you want to read a string containing only alphabets and digits, you can use the `%[ ]` format specifier. Inside the square brackets, you can specify the characters that are allowed.
Syntax
scanf("%[set]", str);
In the code:
To read a string consisting only of alphanumeric characters (letters and digits), you can specify the character set `[a-zA-Z0-9]`.
Here’s the code:
#include <stdio.h>
int main() {
char input[50];
printf("Enter a alphanumeric string: ");
scanf("%[a-zA-Z0-9]", input); // Reads a string with alphabets and numbers
printf("You entered: %s\n", input);
return 0;
}
Expected Output
Enter a alphanumeric string: Hello123
You entered: Hello123
Explanation
If you want to read characters up until a space is encountered (including special characters), you can use the scanset with a space inside the brackets.
Here’s the code:
#include <stdio.h>
int main() {
char input[50];
printf("Enter a string (with spaces): ");
scanf("%[^\n]", input); // Reads until newline is encountered
printf("You entered: %s\n", input);
return 0;
}
Expected Output
Enter a string (with spaces): Hello, World!
You entered: Hello, World!
Explanation
1. Whitespace Handling: If you use `scanf()` with a scanset like `%[^\n]`, it will capture spaces as part of the input. However, the space after a scan (e.g., when typing multiple words) may still cause issues, so be mindful of where you place the scanset.
2. Delimiter Control: You can define more complex delimiters by combining characters within the scanset. For example, `scanf("%[A-Za-z,]", str);` would read only alphabetic characters and commas.
3. Inclusion and Exclusion: You can use `^` inside the brackets to exclude characters. For example, `scanf("%[^0-9]", str);` will read all characters except digits, stopping when a digit is encountered.
In C, taking input that includes spaces can sometimes be tricky with functions like `scanf()`. However, using the `scanset %[ ]` feature of `scanf()`, you can capture strings with spaces by defining appropriate character sets and delimiters. Let's explore some ways to use `scanset` effectively to read strings with spaces.
One of the most common techniques for capturing input with spaces is using the `%[^\n]` scanset. This reads characters until a newline (`\n`) is encountered, effectively capturing an entire line of input, including spaces.
Example
#include <stdio.h>
int main() {
char sentence[100];
printf("Enter a sentence: ");
scanf("%[^\n]", sentence); // Reads until newline, capturing spaces
printf("You entered: %s\n", sentence);
return 0;
}
Expected Output
Enter a sentence: Hello World from C programming!
You entered: Hello World from C programming!
Explanation
You can create a more restrictive input method by specifying which characters are allowed in the input using the scanset. For example, `%[a-zA-Z ]` ensures that only alphabetic characters (both uppercase and lowercase) and spaces are read.
Example
#include <stdio.h>
int main() {
char name[50];
printf("Enter your name (only letters and spaces): ");
scanf("%[a-zA-Z ]", name); // Reads only alphabets and spaces
printf("Name entered: %s\n", name);
return 0;
}
Expected Output
Enter your name (only letters and spaces): Tarush
Name entered: Tarush
Explanation
Although `scanf()` with a scanset like `%[^\n]` is useful, it still has the risk of leaving the newline character in the input buffer, which could cause issues with subsequent input. In such cases, it's often better to use `fgets()` to read the input safely, and then remove the newline manually if necessary.
Example
#include <stdio.h>
int main() {
char sentence[100];
printf("Enter a sentence: ");
fgets(sentence, sizeof(sentence), stdin); // Reads a full line with spaces
// Remove newline character if present
if (sentence[strlen(sentence) - 1] == '\n') {
sentence[strlen(sentence) - 1] = '\0';
}
printf("You entered: %s\n", sentence);
return 0;
}
Expected Output
Enter a sentence: C programming is fun!
You entered: C programming is fun!
Explanation
You can also use the scanset to exclude specific characters. For example, `%[^\n ]` reads until a newline or a space is encountered, which can be useful when you want to read the first part of an input without including any spaces.
Example
#include <stdio.h>
int main() {
char firstName[50];
printf("Enter your full name: ");
scanf("%[^\n ]", firstName); // Reads until space or newline
printf("First name: %s\n", firstName);
return 0;
}
Expected Output
Enter your full name: Rajat Sharma
First name: Rajat
Explanation
Here are some of the key points to remember when using scanset for inputs with spaces:
1. Boundaries: Make sure to define the appropriate boundaries for your input to avoid reading more characters than the buffer can handle. This can help avoid overflow issues.
2. Whitespace: The `%[^\n]` pattern is particularly useful for handling whitespace, but you may need to deal with newlines manually if you use `scanf()`. Functions like `fgets()` can help simplify the process.
3. Flexibility: Scanset gives you the flexibility to define exactly what characters you want to accept and how to handle specific cases (such as spaces, punctuation, or alphanumeric characters).
In C, outputting strings with spaces is straightforward, but it requires an understanding of how the C standard library functions like `printf()` handle strings. Unlike input functions such as `scanf()`, which have limitations when dealing with spaces in strings, outputting strings with spaces is quite simple.
The `printf()` function is commonly used to display strings, and it naturally handles spaces in strings, printing everything from the memory block that represents the string, including spaces and special characters.
Example
#include <stdio.h>
int main() {
char sentence[100]; // Allocate buffer to store user input
printf("Enter a sentence: ");
fgets(sentence, sizeof(sentence), stdin); // Read input including spaces
printf("You entered: %s", sentence); // Output the string, spaces included
return 0;
}
Expected Output
Enter a sentence: C programming is awesome!
You entered: C programming is awesome!
Explanation
One thing to be aware of when using `fgets()` is that it retains the newline character (`\n`) at the end of the input string. This may or may not be desired in the output, depending on the specific use case.
Example (Removing Newline Character)
#include <stdio.h>
#include <string.h>
int main() {
char sentence[100];
printf("Enter a sentence: ");
fgets(sentence, sizeof(sentence), stdin); // Read input including spaces
// Remove the newline character if it exists
size_t len = strlen(sentence);
if (len > 0 && sentence[len - 1] == '\n') {
sentence[len - 1] = '\0'; // Replace newline with null terminator
}
printf("You entered: %s\n", sentence); // Output without the newline
return 0;
}
Expected Output
Enter a sentence: Hello World
You entered: Hello World
Explanation
1. Newline Handling: If you use `fgets()` to read the input, always check and remove the newline character (`\n`) if you don't want it to appear in the output.
2. No Special Handling for Spaces: Unlike input, spaces in strings are automatically preserved when outputting with `printf()`. You don't need to do anything special for spaces to be printed correctly.
3. Buffer Size: Make sure the buffer size for the string is large enough to hold the entire input, including spaces and the null terminator. If the input exceeds the buffer size, `fgets()` will stop reading and may leave the remainder of the input in the buffer.
In C programming, handling strings, especially when dealing with spaces, requires understanding the nuances of input and output functions. While functions like scanf() are widely used for string input, they come with limitations, such as stopping at spaces or newlines.
Furthermore, to work around this, functions like fgets() and scanset in scanf() offer more control, enabling you to read strings that include spaces. Choosing between these options depends on the specific use case, and it's crucial to remember that each function has its own advantages and potential pitfalls, such as buffer overflows or unintended newline characters.
Additionally, proper buffer management, understanding how different input functions behave, and knowing when to use safe alternatives like fgets() instead of gets() can help prevent errors and improve the robustness of your programs. Overall, mastering string handling in C is key to building efficient, secure, and user-friendly applications.
`scanf()` reads input until it encounters a space or newline, making it unsuitable for input with spaces. `fgets()`, on the other hand, reads the entire line, including spaces, until a newline is encountered.
By default, `scanf()` will stop reading at the first space. However, you can use `scanf("%[^\n]", str)` to read input with spaces until a newline is encountered.
`fgets()` is safer because it allows you to specify the maximum size of the buffer, preventing buffer overflows. It also reads the entire line, including spaces, making it more flexible.
`scanf("%s")` is designed to read only a single word or token. It considers spaces as delimiters, which is why it stops at the first one.
`fgets()` reads the newline character as part of the input. To remove it, check if the last character is a newline (`\n`) and replace it with the null terminator (`\0`).
No, `scanf()` with `%s` will only read a single word until it encounters a space. To read multiple words, consider using `fgets()` or `scanf("%[^\n]", str)`.
A scanset (denoted as `%[ ]`) in `scanf()` allows you to specify a set of acceptable characters. It can be used to limit the input to specific characters, such as alphanumeric characters, or to read strings with spaces.
Always specify the maximum size of the buffer when using `scanf()` or `fgets()`. For example, use `scanf("%49s", str)` or `fgets(str, 50, stdin)` to ensure you don’t exceed the buffer size.
It is not recommended to use `gets()` because it does not perform bounds checking, leading to potential buffer overflows. Use `fgets()` instead for safer input handling.
Using `printf()` will output a string with spaces without any special handling. You just need to pass the string as an argument, and `printf()` will preserve the spaces.
You can use `scanf("%[^\n]", str)` or `fgets()` to read input with spaces and special characters. Both methods will capture everything until a newline is encountered, allowing for more flexible input handling.
Take a Free C Programming Quiz
Answer quick questions and assess your C programming knowledge
Author
Start Learning For Free
Explore Our Free Software Tutorials and Elevate your Career.
Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)
Indian Nationals
1800 210 2020
Foreign Nationals
+918068792934
1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.
2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.