how to make a string empty in C - c

I'm using C here.
char a[4], b = 'A';
int k = 0, count = 0;
while true {
if count == 26
break;
if k == 4 {
k = 0;
count++;
b++;
//I want the solution code here.
printf("%s", a);
}
a[k] = b;
k++;
}
I need to know that, If a string in C got assigned completely, is it possible to empty that string again? I can show you my desired output.
AAAABBBBCCCC........ZZZZ
Please help me.

A couple of ways come to mind. Given that strings in C are usually terminated by an ASCII zero, the easiest would be to set the first byte to zero.
a[0] = '\0';
Now this doesn't erase all the characters in the string, but since the first character is now a termination character the string looks empty to your program.
If you want to erase all the characters in the string then you need to use a loop.
OR
Another way might be to use memset() to set the whole string to zeros.
memset(a, 0, strlen(a));
but this will only work for zeroing up to the first NULL character.

In your case, it should suffice to do:
a[0] = '\0';
This sets the first char in the string to be the null terminating character, such that when you print the string, it prints an empty string.
You should also assign the null terminating character to after the effective last character:
a[0] = 'a';
a[1] = 'b';
a[2] = '\0';
printf("%s", a); //print "ab"

You can do
a[0] = '\0';
or
strcpy(a, "");
But your code seem to have a general problem with string termination.
In C a string is terminated (i.e. it ends) with the character '\0' and you code fails to add that termination. You could do:
a[k] = b;
a[k+1] = '\0';
or
if k == 4 {
a[k] = '\0';
If you call printf and the string isn't terminates, you program may crash.
Also notice that char a[4]; should be char a[5]; as you need to store things like "AAAA\0", i.e. 5 characters because you need the 4 A plus a termination.

As you are building 4 letters strings, so you need an array of size 5.
A string must be ended with \0, if not it is not a string, see standard:
7.1.1 Definitions of terms
1 A string is a contiguous sequence of characters terminated by and including the first null character.
You don't need to reset the string as you only print it when it will be correctly filled, you just have to fill it while looping as you did it.
char a[5], b = 'A';
int k = 0, count = 0;
a[5] = '\0'; // mark end of string
while true {
if (count == 26)
break;
if (k == 4) {
k = 0;
count++;
b++;
printf("%s", a);
}
a[k] = b;
k++;
}

Related

Extra character appearing on string in C Program

I'm working on a homework problem that involves making a word search program. The letter grid and words are taken from an input file. I have the grid stored in an array and I want to turn the rows and columns into discrete strings so that I can use the strstr function on them to find a word. I wanted to test that I created a string properly and I'm finding it has two extra characters on the end of it. Why is this? BTW The size variable is equal to 5 and was used to define the dimensions of the array.
char line[size+1];
int i;
for (i = 0; i < size; i++) {
line[i] = grid[0][i];
printf("character %c \n", grid[0][i]);
}
line[size+1] = '\0';
printf("test string %s \n", line);
Here's the output including the printed word grid.
A L P H A
B O F L A
B C P Z T
B H H A E
A T X Y B
test string ALPHA'
When working with strings to denote the end of a string array the last element should always contain a null character '\0' maybe you havent assigned that because of which it is having garbage value in that place
P.S. array size is always n+1 of the actual string so that it can contain the termination character
You add the null character at an index outside of the char array. Array indexes begin with zero but you treat it like the first index is 1.
As an example, this outputs "test string ALPHAX" since the null character is added outside of the array and not in the last element:
int size = 5;
char line[size+1];
int i;
line[0] = 'A';
line[1] = 'L';
line[2] = 'P';
line[3] = 'H';
line[4] = 'A';
line[5] = 'X';
line[size+1] = '\0'; // size+1 is 6
printf("test string %s \n", line);
Change line[size+1] = '\0'; to line[size] = '\0'; in your code like below and it should work as expected.
char line[size+1];
int i;
for (i = 0; i < size; i++) {
line[i] = grid[0][i];
printf("character %c \n", grid[0][i]);
}
line[size] = '\0';
printf("test string %s \n", line);

How to do read multiple characters from an argument

I am trying to read multiple characters from an argument in c. So when the person rules the file like "./amazing_program qwertyyuiopasdfghjklzxcvbnm" it would read the qwerty characters and store the, into a array as a number (ASCII) like:
array[0] = 'q';
array[1] = 'w';
array[2] = 'e';
array[3] = 'r';
array[4] = 't';
array[5] = 'y';
and so on...
My goal: Is to separate the argument into each individual character and store each individual character into a different place in the array (like shown above).
I tried this way, but it didn't work.
int user_sub = 0;
int argument = 1;
while (argument < argc) {
user_sub = atoi(argv[argument]);
argument = argument + 1;
}
From reading your comments, I've come to understand you just want to be able to get to the characters so you can do a shift. Well, that's not so hard to do, so I've tried to show you how you can do it here without having to complete the Caesar logic for you.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SHIFT 13
int main (int argc, const char *argv[]) {
// Verify they gave exactly one input string.
if (argc != 2) {
fprintf(stderr, "Usage: %s <word>\n", argv[0]);
exit(EXIT_FAILURE);
}
// A string IS already an array of characters. So shift then and output.
int n = strlen(argv[1]);
for (int i = 0; i < n; i++) {
char c = argv[1][i];
// Shift logic here: putchar(...);
printf("%d: %c\n", i, c);
}
return EXIT_SUCCESS;
}
The key takeaway is that a string is already an array. You don't need to make a new array and stick all the characters in it. You already have one. What this program does is simply "extract" and print them for you so you can see this. It currently only writes the current argument string to output, and does no shifting. That's for you to do. It also doesn't take into account non-alphabetical characters. You'll have to think about them yourself.
You have serious lack :
1)
A string in C is an ARRAY of type char. We know where the end of the array is thank to a special value : '\0'.
Now, you have to deeply understand that each case of the array contain a NUMBER : since the type of the case is char, it will be a number in the range [-128, 127] (yeah, I know that char is special and can be signed or not, but let's keep it simple for the time being).
So if you acces each case of the array and print it, you will have a number between -128 and 127. So how the program know to print a letter instead of a number ? And how do he know which letter for which number ?
Thank to an internal table used for this uniq purpose. The most common is the ASCII table. So if a case of the array is 65, what will be printed is 'A'.
2) How can I go through each case of a string ? (which is an array of char terminated by '\0') ?
Simply with a for loop.
char str[] = "test example";
for (size_t i = 0; str[i] != '\0'; ++i) {
printf("The %d letter is '%c'\n", i, str[i]);
}
Again, since it's a number in str[i], how the program know how to print a letter ? Thank to the "%c" in printf, meaning "print the letter using the table (probably ASCII)". If you use "%s", it's the same thing, but you have to give the array itself instead of a case of the array.
So, what if I want to print the number instead of the letter ? Just use "%d" in printf.
char str[] = "test example";
for (size_t i = 0; str[i] != '\0'; ++i) {
printf("The %d letter is '%c' and it's real value is %d\n", i, str[i], str[i]);
}
Now, what if we increment all the value in each case of the string ?
char str[] = "test example";
for (size_t i = 0; str[i] != '\0'; ++i) {
str[i] = str[i] + 1; // Or ++str[i];
}
for (size_t i = 0; str[i] != '\0'; ++i) {
printf("The %d letter is '%c' and it's real value is %d\n", i, str[i], str[i]);
}
We have changed the string "test example" into "uftu fybnqmf".
Now, for your problem, you have to take the resolution step by step :
First, make a function that alter (cypher) a string given in argument by adding a shift.
void CesarCypherString(char *string);
Beware of "overflow" ! If I want to have a shift of 5, then 'a' will become 'f', but what happen for 'z' ? It should be 'e'.
But if you look at the ascii table, 'a' = 97, 'f' = 102 (and it make sense, since 'a' + 5 = 'f', 97 + 5 = 102), but 'z' is 122 and 'e' is 101. So you cannot directly do 'z' + 5 = 'e' since it's wrong.
Hint : use modulo operator (%).
Next, when you have finished to do the function CesarCypherString, do the function CesarDecypherString that will decypher a string.
When you have finished, then you can concentrate on how to read/duplicate a string from argv.

which code is better ? and how do we understand that ? why is the final print function in the second code sometimes printing random numbers?

I am very new here .. so please excuse me if my question is really unnecessary .. but I think the answer will help me have some faith in myself ..here are two code snippets ..one i got on the website c4learn.com ..
#include<stdio.h>
int main()
{
char s1[100], s2[100];
int i;
printf("\nEnter the string :");
gets(s1);
i = 0;
while (s1[i] != '\0')
{
s2[i] = s1[i];
i++;
}
s2[i] = '\0';
printf("\nCopied String is %s ", s2);
return (0);
}
and the other i wrote myself ..
#include<stdio.h>
int main()
{
char s1[100], s2[100];
int i;
printf("\n Enter the string 1");
gets(s1);
printf("\n Enter the string2");
gets(s2);
for(i=0;i<100;i++)
{
if (s1[i]!='\0')
{
s2[i]=s1[i];
}
}
s2[i]='\0';
printf("\n Copied string is %s ", s2);
return(0);``
}
the problem is while running the code on dev c++ .. the final printf displayed is showing some random characters at the end of the string .. Can anyone help me understand that and which is code is better ? the initial question was ... HOW WILL YOU COPY ONE STRING TO ANOTHER WITHOUT USING ANY INBUILT LIBRARIES ? thank you ..
Your code is not quite right:
Why do you ask for the user input for s2 if you then overwrite it, copying s1?
The for cycle you wrote doesn't stop when s1 is over (I mean the null terminator character '\0') so you are also copying all the chars remaining in s1 after '\0'. If the chars in the array are not initialized (and that's the case for chars after '\0') they of course might result in random characters.
So answering your question, the first code is the right way to do it.
Any way if you want to use a for cycle you could do:
for (i = 0; i < 100; i++) {
s2[i] = s1[i];
if (s1[i] == '\0')
break;
}
You have to break out of the loop when you reach the null terminator character \0. The first code breaks out of the while loop while you're code continues on until i == 100 skipping over the null character. This is why its printing garbage past the original string.
This is what you should do to break out after the null character.
for (i = 0; i < 100; i++) {
s2[i] = s1[i];
if (s1[i] == '\0') break;
}
In the second block of code, after exiting the for loop, i has a value of 100. So you're putting the 0 byte at index 100.
Since an array of size 100 has indexes 0 to 99, you're writing past the end of the array. That causes undefined behavior.
When you're inside of the for loop, you need to break out after you find the null byte.
Also, both programs use gets which is unsafe because it does not perform any bounds checking and may write past the end of the array.

Trying to remove all numbers from a string in C

I'm trying to take all of the numbers out of a string (char*)...
Here's what I have right now:
// Take numbers out of username if they exist - don't care about these
char * newStr;
strtoul(user, &newStr, 10);
user = newStr;
My understanding is that strtoul is supposed to convert a string to an unsigned long. The characters that are not numbers are put into the passed in pointer (the 2nd arg). When i reassign user to newStr and print it, the string remains unchanged. Why is this? Does anyone know of a better method?
From the documentation example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char str[30] = "2030300 This is test";
char *ptr;
long ret;
ret = strtoul(str, &ptr, 10);
printf("The number(unsigned long integer) is %lu\n", ret);
printf("String part is |%s|", ptr);
return(0);
}
Let us compile and run the above program, this will produce the following result:
The number(unsigned long integer) is 2030300
String part is | This is test|
char* RemoveDigits(char* input)
{
char* dest = input;
char* src = input;
while(*src)
{
if (isdigit(*src)) { src++; continue; }
*dest++ = *src++;
}
*dest = '\0';
return input;
}
Test:
int main(void)
{
char inText[] = "123 Mickey 456";
printf("The result is %s\n", RemoveDigits(inText));
// Expected Output: " Mickey "
}
The numbers were removed.
Here is a C program to remove digits from a string without using inbuilt functions. The string is shifted left to overwrite the digits:
#include <stdio.h>
int main(void) {
char a[] = "stack123overflow";
int i, j;
for (i = 0; a[i] != '\0'; i ++) {
if (a[i] == '0' || a[i] == '1' || a[i] == '2' || a[i] == '3' || a[i] == '4' || a[i] == '5' || a[i] == '6' || a[i] == '7' || a[i] == '8' || a[i] == '9') {
for (j = i; a[j] != '\0'; j ++)
a[j] = a[j + 1];
i--;
}
}
printf("%s", a);
return 0;
}
Example of execution:
$ gcc shift_str.c -o shift_str
$ ./shift_str
stackoverflow
strtoul() does not extract all numbers from string, it just trying to covert string to number and convertion stops when non digit is find. So if your string starts from number strtoul() works as you expect, but if string starts from letters, strtoul() stops at the first symbol. To solve your task in simple way you should copy all non-digits to other string, that will be a result.
The problem you are having is that strtoul is converting characters at the beginning of the string into an unsigned long. Once it encounters non-numeric digits, it stops.
The second parameter is a pointer into the original character buffer, pointing at the first non-numeric character.
http://www.cplusplus.com/reference/cstdlib/strtoul/
Parameter 2 : Reference to an object of type char*, whose value is set by the function to the next character in str after the numerical value.
So, if you tried to run the function on "123abc567efg" the returned value would be 123. The original string buffer would still be "123abc567efg" with the second parameter now pointing at the character 'a' in that buffer. That is, the pointer (ptr) will have a value 3 greater than original buffer pointer (str). Printing the string ptr, would give you "abc567efg" as it simply points back into the original buffer.
To actually remove ALL the digits from the string in C you would need to do something similar to this answer : Removing spaces and special characters from string
You build your allowable function to return false on 0-9 and true otherwise. Loop through and copy out digits to a new buffer.

converting new line character

I am trying to convert new line character \n to dos style which is \r\n , without using libc.
here is my attempt, what am I doing wrong?
for(i = 0; str[i]!='\0'; ++i)
{
if ('\r' == str[i] && '\n'==str[i+1])
++count;
}
strPtr = malloc(i + 1 + count);
for(i = j = 0; str[i]!='\0'; ++i)
{
if ('\r' == str[i])
strPtr[j++] = "";
}
strPtr[j] = 0;
output should now be
"Hi\r\n, How are you \r\n, are you okay\r\n"
There are many problems here. Firstly, you are modifying the string in place using the original buffer. However, the original buffer does not have enough space to store the additional \r characters. You'll need to allocate a larger buffer.
Secondly, a UNIX-style carriage return character is not stored as two separate \ and n characters. It is a single ASCII character with a value of 0xA, which can be represented using the escape sequence \n. So to check if your current character is a newline character, you want to say strPtr[i] == '\n'
Finally, you are overwriting the old buffer when you say strPtr[i-1] = '\r'. This will replace the character before the \n, (such as the i in Hi).
Basically, what you want to do is create a second buffer for output, and copy the string character by character to the output buffer. When you encounter a \n character, instead of copying a single \n to the new buffer, you copy \r\n.
The size of the output buffer needs to be twice the size of the input buffer to handle the case of an input string where every character is \n, plus 1 for the NULL terminator. However, you can compute an optimal size for the output buffer by counting the number of \n characters in the original string beforehand.
All the escape sequence characters in C language are one character which is stored in one byte of memory only, dont consider it as two.
So you can directly check for a byte to \n as you are checking for \0.
If you want to replace \n(1 character) with \r\n(2 character) means, str should have additional memory, but in your program its not having additional memory.
char *a = "\n"; //This is one byte
char *b = "\\\n"; //This is two byte, 1st byte for '\' and 2nd byte for new line
char *c = "\\\r\n"; //Similarly this is three byte
char *c = "\r\n"; //Similarly this is two byte
All the below escape sequence characters are single byte character in C language.
\n – New line
\r – Carriage return
\t – Horizontal tab
\\ – Backslash
\' – Single quotation mark
\" – Double quotation mark
You can't do this in-place. You're adding a new character ('\r') for every '\n' which means the string must expand. The worst case scenario is that every character is a '\n' which means we would double the size of the string. Thus, let's make a buffer twice the size of the original string.
strtmp = malloc(strlen(str) * 2 + 1); /* +1 for null */
strcpy(strtmp, str);
strptr = strtmp;
for (i = 0; str[i] != 0; i++)
{
if ((str[i] == '\\') && (str[i+1] == 'n'))
{
*strptr++ = '\\';
*strptr++ = 'r';
}
*strptr++ = str[i];
}
printf(strtmp);
free(strtmp);
The \n in your string is an escape sequence and is represented by one character.
Your code should be like this:
int main(void)
{
char str[] = "Hi\n, How are you \n, are you okay\n";
char *strPtr = str;
int i, j;
int count=0;
for(i = 0; str[i]!='\0'; ++i)
{
if (`\n` == str[i]) ++count;
}
strPtr = malloc(i + 1 + count);
for(i = j = 0; str[i]!='\0'; ++i)
{
if ('\n' == str[i]) strPtr[j++] = `\r`;
strPtr[j++] = str[i];
}
strPtr[j] = 0;
printf("This many times we changed it", count);
}
EDIT
As you have decided to change the question (BTW - Just add to the question for clarification and not delete huge chunks of the original OP as the answers will not make any sense for future visitors) - here is the code:
int main(void)
{
char str[] = "Hi\r\n, How are you \r\n, are you okay\r\n";
int i, j;
for (i = j = 0; 0 != str[i]; ++i)
{
if ('\r' == str[i] && '\n' == str[i + 1])
{
++count;
}
else
{
str[j++] = str[i];
}
}
str[j] = 0;
.. etc - str is without \r\n but \n, count is the number of lines.

Resources