Extra character appearing on string in C Program - arrays

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);

Related

Reversing a word in C and then storing that reversed word to use in a printf

So basically I'm trying to reverse a word (a single word, not a string with multiple words) and I've managed to reverse the word using this
{
int end, x;
end = strlen(myString) - 1;
for (x = end; x >= 0; --x) {
printf("%c", myString[x]);
}
}
(myString is defined somewhere else in the code)
But here's the kicker, I need to print the reversed word like this:
printf("The word reversed is '%c'", myString);
And I've no idea how to actually take the word reversed by the for loop and putting it into the second printf command. Any ideas?
Here you are.
for ( size_t i = 0, n = strlen( myString ); i < n / 2; i++ )
{
char c = myString[i];
myString[i] = myString[n - i - 1];
myString[n - i - 1] = c;
}
printf("The word reversed is '%s'\n", myString);
If the string you are passed is a literal instead of an allocated pointer, you'll need to make a reverse-copy of the string into an allocated buffer. Same applies if you are trying to avoid corrupting the orignial string.
// allocate a buffer big enough to hold a copy of the string
int len = strlen(myString);
char* reverse = malloc(len+1);
// reverse copy it over.
for (size_t i = 0; i < len; i++)
{
reverse[i] = myString[len-1-i];
}
reverse[len] = '\0'; // null terminate our new string
printf("Reversed word: %s\n", reverse);
// free the string when you are done with it
free(reverse);

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.

how to make a string empty in 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++;
}

Concatenation of first halves of two separate strings

How can I write C-program which accepts two strings from the user and prints a string which is the result of the concatenation of the first half of the two strings. For odd length strings, extra character goes in the first half of the string.
I have this so far but am confused on the splitting in half part...
printf("Please enter your first word.\n"); //Asks for first string
scanf("%s",&c); //Takes first string
printf("Please enter your second word.\n"); //Asks for second string
scanf("%s",&d); //Takes second string
strcat(c,d); //Combines both strings
If you just want to print out the result not caring about the content of the strings c and d any more you could do something like
#include <stdio.h>
#include <string.h>
int main(void) {
char c[1024]; // c string buffer
char d[1024]; // d string buffer
// initialize to empty strings
c[0] = '\0';
d[0] = '\0';
// read strings c and d
scanf("%s", c);
scanf("%s", d);
// just to make sure there is no overflow
c[1023] = '\0';
d[1023] = '\0';
// cut strings in middle
c[(strlen(c) + 1)/2] = '\0';
d[(strlen(d) + 1)/2] = '\0';
// print final string
printf("%s", c);
printf("%s\n", d);
return 0;
}
The result of (strlen(c) + 1)/2 does what you want because it performs an integer division. If strlen(c) gives an even size then adding 1 would make it the next odd with no effect on the integer division. If on the other hand the number is odd adding one will make it the next even achieving the rounding up you need. The '\0' will make sure that the string is terminated at that point.
If you don't want to loose the information of the two strings or need the resulting string stored then you could do something like
#include <stdio.h>
#include <string.h>
int main(void) {
char c[1024]; // c string buffer
char d[1024]; // d string buffer
char r[1024]; // resulting string buffer
int i; // general counter
int c_half_len; // c half length
int d_half_len; // d half length
// initialize to empty strings
c[0] = '\0';
d[0] = '\0';
r[0] = '\0';
// read strings c and d
scanf("%s", c);
scanf("%s", d);
// just to make sure there is no overflow
c[1023] = '\0';
d[1023] = '\0';
// get c and d half lengths rounding up
c_half_len = (strlen(c) + 1)/2;
d_half_len = (strlen(d) + 1)/2;
// copy first half c string to begining of result
for (i = 0; i < c_half_len; ++i) {
r[i] = c[i];
}
// copy first half d string after the end of the first half string
for (i = 0; i < d_half_len; ++i) {
r[c_half_len + i] = d[i];
}
// add an end of string character
r[c_half_len + d_half_len] = '\0';
// print final string
printf("%s\n", r);
return 0;
}
In both cases I assume that the two strings have a maximum length, in this case 1024 (including the end of string character). If that is not the case then you will need to handle things using dynamic memory.
void concathalf(const char *a, const char *b, char *out)
{
char *abuf, *bbuf;
if ((abuf = malloc(strlen(a) / 2)) && (bbuf = malloc(strlen(b) / 2))) {
memcpy(abuf, a, strlen(a) / 2);
memcpy(bbuf, b, strlen(b) / 2);
abuf[strlen(a) / 2] = bbuf[strlen(b) / 2] = 0;
}
sprintf(out, "%s%s", abuf, bbuf);
free(abuf);
free(bbuf);
}
Now, handling odd length inputs will be left as an exercise.

Unwanted characters after word in output

I created a program that asks the user for a word and then it arranges the letters in that word in alphabetical order and stores it in another string.
#include <stdio.h>
main()
{
char in[100],out[100],ch;
int i,len,j=0;
//ask user for a word
printf("Enter a word: ");
scanf("%s",in);
//arrange that word in alphabetical order
for(ch = 'a'; ch <= 'z'; ++ch)
for(i = 0; i < strlen(in); ++i)
if(in[i] == ch)
{
out[j] = ch;
++j;
}
//print the word
printf("%s",out);
fflush(stdin);
getchar();
}
The problem is when word is stored in the other string, there are some extra letters or symbols after that word. Can someone please tell me what could be possibly wrong with my code?
You're not null terminating the output string. printf("%s",out); will keep outputting characters until it finds 0 ('\0'). There are many options to fix this:
terminate the output to the current iterator position after the for-loop:
out[j] = '\0';
make the output the same length as the input:
out[strlen(in)] = '\0';
declare a 0-initialized array:
char out[100] = { 0 };
fill the output array with zero's yourself:
memset(out, 0; sizeof(out));
...
As the sorting is concerned, if it's just for learning then it's fine, otherwise you should pick a more efficient sorting algorithm
C strings are null terminated
Use
out[j] ='\0';
before printf
The %s specifier searches for a null termination.
In your case it keeps on printing until it finds one, so you get some random symbols.
Also avoid use of fflush.
You might want to update your logic to sort uppercase characters too.
You might want to use a sort say bubble sort
l=strlen(in);
for(i = 0; i < l; i++)
{
for(j = i + 1; j < l - 1; j++)
if(in[j-1] > in[j]){
ch = in[j];
in[j] = in[j-1];
in[j-1] = ch;
}
}
printf("Sorted String :%s",in);

Resources