reversing a string in C - c

#include <stdio.h>
void reverse(int len, char s[], char b[]);
int main() {
char s[5] = "hello";
char b[5];
reverse(5, s, b);
return 0;
}
void reverse(int len, char s[], char b[]) {
int i;
for (i = 0; i < len; i++) {
b[(len - 1) - i] = s[i];
}
printf("%s : %s\n", s, b);
printf("%s", b);
}
Here is my code above in C. When I run it, it switches the string s[] to b[] but b[]also includes s[]. Can someone please thoroughly explain what I'm doing wrong? I really appreciate it.

char s[5] = "hello";
This is wrong, you need one more [6] in order to store the trailing '\0' (same for b)
It's better to omit the array size:
char s[] = "hello";
char b[sizeof(s)];
And you need b[i] = '\0'; after the for loop.

Your string buffers are too small, they must be six characters or more to hold the string "hello". Remember that strings C have a terminating '\0'-character at the end; that won't fit with space for only five characters.
Also, when reversing you never copy the terminating character.
You need b[len - 1] = '\0'; before exiting reverse().
When you pass non-terminated strings to printf()'s "%s" format, you get undefined behavior. Typically it "runs off the end" of the string, printing whatever it happens to find in memory, until it finds a character with the value 0 which causes it to stop.

The %s format specifier expects a string: An array of characters ending in a nul byte. You are not supplying that, so you are getting rubbish results. To hold a string with five characters, you need at least six chars.

every string in c is terminated by \0 which is a null character. so the array size should be enough to hold the string along with null character.
I will suggests to increase the size of array.
important :-
at the last assign b[last_index]='\0';
so that string b can be terminated by \0. otherwise it might give garbage values along with actual data while printing the string b.

In C, you just need to include
#include<string.h>
and use
strrev(a);
where a is the character array or string.
Whereas, your code can be modified too, to be written like this
#include <stdio.h>
void reverse(int len, char s[], char b[]);
int main() {
char s[5] = "hello";
char b[5];
reverse(5, s, b);
return 0;
}
void reverse(int len, char s[], char b[]) {
int i,j;
for (i = 0,j=len-1; i <=j; i++, j--) {
b[j]=a[i];
}
printf("%s : %s\n", s, b);
printf("%s", b);
}

Related

Taking multiple strings through scanf

When I try to use scanf() to read one string of chars, everything works.
In the code below, I read two strings of chars, but if I input "abcde abcde" (arbitrary letters), printf() prints " is your character".
int main(){
char A[5], B[5];
scanf("%s %s", A,B);
printf("%c is your character", A[0]);
}
What am I doing wrong?
You are typing one string of length 5 (+1 with \0) and try to put it in a char table of size 5, which is an undefined behavior.
If you want to put “abcde” in both A and B, you need to increase the size of A and B to at least 6.
As #pmg pointed out already, the char array has to be long enough to have the null-terminator at the end of it, thus abcde abcde doesn't work, but abcd abcd works. If you would like to solve this statically, literally just stretch the size of the array buy how much you need:
char A[40], B[40];
However, if you really insist on getting dynamic allocation, you could use getline(), then malloc on some char* of the length of your input string (worst case scenario), and then use sscanf to split your input stringo to A and B.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* I = NULL;
char* A;
char* B;
size_t len = 0;
if (getline(&I, &len, stdin) != EOF)
{
A = (char*)malloc(len + 1);
B = (char*)malloc(len + 1);
sscanf(I, "%s %s", A, B);
printf("%c is your character", A[0]);
free(A);
free(B);
}
free(I);
return 0;
}

string not printing properly in C

I am encountering a problem while printing out a string using a while loop in a standalone function.
I have the following code:
#include <stdio.h>
int pword(char *);
int main() {
char s[] = "Alice";
pword(s);
return 0;
}
int pword(char *s) {
while(*s!='\0') {
printf("%s", s);
s++;
}
printf("\n");
return 0;
}
This is printing: Aliceliceicecee.
you're printing the offseted word each time, instead of the character.
Try changing (for instance)
printf("%s", s);
by
printf("%c", *s);
or since you don't really need formatting, use
putchar(*s);
(all this means that you're basically rewriting puts with a loop. So if no further processing is required on the characters, maybe you should just stick with standard functions)
%s means expect a const char * argument
%c means expect a character argument. The character argument is printed. Null characters are ignored;
You are looking for later one.
More info on %s: The argument is taken to be a string (character pointer), and characters from the string
are printed until a null character or until the number of characters indicated by the
precision specification is reached; however, if the precision is 0 or missing, all characters up to a null are printed;
Seeing no answer explained what exactly was going on, here is what you are actually doing:
int pword(char *s) { /* s = "Alice" (s is a char* that holds the address of "Alice" string)*/
while(*s!='\0') { /* check if the first char pointed to by s != '\0' */
printf("%s", s); /* print the string that start at s*/
s++; /* move s (the char pointer) 1 step forward*/
} /* s points to "lice" -> "ice" -> "ce" -> "e" */
printf("\n");
return 0;
}
In order to print the string "Alice" you could have just used printf("%s", s); as it would take the address pointed to by s, where "Alice" is stored, and print it until reaching null-terminator ('\0').
If you want to use a loop and print char by char, you should have used printf("%c", *s);. Using %c is meant for printing char where %s is for printing strings. Another thing to note is the s vs *s, where the former is a char* (pointer to char) that can hold number of consecutive chars, and the later (*s)is *(char*) i.e. dereferenced char*, that holds a single char.
To sum up:
print char by char
int pword(char *s) {
while(*s!='\0') {
printf("%c", *s);
s++;
}
printf("\n");
return 0;
}
print the whole string at once
int pword(char *s) {
printf("%s\n", s);
return 0;
}
If you want to print character by character, you should use *s in the printf statement like below.
#include <stdio.h>
int pword(char *);
int main() {
char s[] = "Alice";
pword(s);
return 0;
}
int pword(char *s) {
while(*s!='\0') {
printf("%c", *s);
s++;
}
printf("\n");
return 0;
}

Resultant string utilising puts and strcat showing extra characters

#include<stdio.h>
#include<string.h>
int main()
{
char c='g';
char d[]="John ";
strcat(d,&c);
puts(d);
return 0;
}
The output is:
John gC
The 'C' wasn't required.
Also, what does const char* mean here?
char *strcat(char *dest, const char *src)
Also, is a statement like this (inside a loop) wrong somewhere if I wish to add a character at the end of string?
char arr[]=' ';
symb[]={'a','b','c'}
strcat(arr, &symb[k]);
k++;
You are writing out of the bounds of d, you need room for one more char, change to
char d[7] = "John ";
or (if you don't want to specify the size of the array):
char d[] = "John \0";
or
char d[] = {'J', 'o', 'h', 'n', ' ', '\0', '\0'};
Also strcat wants a valid NUL terminated string and you are passing a pointer to a single char, change to
char *c= "g";
Two ways(there are even more):-
1>
char *c="g";
char d[10]="John ";
strcat(d,c);
2>
char c[]="g";
char d[10]="John ";
strcat(d,c);
Though I advise d[10] = {0} ; and then copy the string. (as David mentioned in comments.)
You need to learn the basics of C and C-style strings. Specifically, that a special zero-value character identifies the end of the string.
You have copied over the string but you did not copy the terminator. Therefore, functions like puts() don't know when to stop and print other characters that happen to be in memory.
There is undefined behaviour in your program . strcat requires null terminated string as its arguments where c is not . You can do this-
char c[]="g";
char d[7]="John "; // leave space for 'g' as well as for '\0'
strcat(d,c); // then pass both to strcat
Another way is to use sprintf -
char c[]="g";
char d[10]="John";
size_t n =strlen(d);
sprintf(&d[n]," %s",c);
This works: ( if you wanted John g )
#include<stdio.h>
#include<string.h>
int main()
{
char c='g';
char d[10];
char temp[2];
strcpy(d ,"John ");
temp[0]=c;
temp[1]='\0';
strcat( d , temp );
puts(d);
return 0;
}
This works: ( if you wanted Johng )
#include<stdio.h>
#include<string.h>
int main()
{
char c='g';
char d[]="John ";
//strcat(d,&c);
d[strlen(d)-1]=c;
puts(d);
return 0;
}

Is there any function available for printing some characters instead of whole strings?

see
char str[] = "hello world";
printf("%s",str);
printf statement prints the all character in string before reaching '\0'
so what if i want to print just 4 1st character of str on stdout?
You can just specify the field width in the printf format string:
#include <stdio.h>
int main(void)
{
const char *s = "Hello world !";
printf("%.4s\n", s);
return 0;
}
or, if you want to specify the field width at run-time:
#include <stdio.h>
int main(void)
{
const char *s = "Hello world !";
const int fw = 4;
printf("%.*s\n", fw, s);
return 0;
}
In either case the output will be:
Hell
You can use %c in your format string:
printf("%c", *s);
prints 'H'
To print an arbitrary char:
printf("%c", s[3]);
prints 'l'
For the first character, you can just use:
printf ("%c", *str); // or
printf ("%c", *(str+0)); // or
printf ("%c", str[0]);
For a different character, just reach out and grab it by using an offset. For the second l at offset 3:
printf ("%c", str[3]); // or
printf ("%c", *(str+3));
For a substring, you can use a combination of that method along with the maximum field width feature of printf:
printf ("%.2s", str+3); // prints "lo"
With all these solutions, you want to make sure you don't start on the wrong side of the null terminator. That wouldn't be a good thing :-)
If you want a generalised solution that will work for any string, and is relatively safe in terms of finding the starting point, you can use:
void outSubstr (FILE *fh, char *str, size_t start, size_t sz, int padOut) {
if (start >= strlen (str)) {
if (padOut)
fprintf (fh, "%*s", sz, "");
return;
}
if (padOut)
fprintf (fh, "%-*.*s", sz, sz, str + start);
else
fprintf (fh, "%-.*s", sz, str + start);
}
The parameters are as follows:
fh is the file handle to write to.
str is the start of the string.
start is the offset to start printing from.
sz is the maximum number of characters to print.
padOut is a flag indicating that sz is also the minimum size. Output will be padded with spaces on the right if there are not enough characters in the string to satisfy the size.
This will print up to 4 characters.
printf("%.4s", str);
there is also a "substr()" function
that return the substring from complete string.
example
printf("%s",substr(str,0,4));
it has syntax like this
substr(arrayName,charStartingPosition, lengthOfCharacters);
i hope this is easy to understand and no need to write more than 1 statement.
Really less painful for the system :
int main(void)
{
char c;
c = 'z';
write(1, &c, 1);
}
No need for heavy stdio here
Then you can ...
char *s = "Hello, World!";
write(1, s, numberOfChars);
Or if you really want to do it char by char:
void printnchars(char *s, int n)
{
int i;
i = 0;
while (i <= n)
{
write(1, s + i, 1);
i++;
}
}
numOfChars = 4;
printf("%.*s\n", numOfChars, "Hello, world!");
Where numOfChars is the quantity of characters that you want to print.

How to iterate over a string in C?

Right now I'm trying this:
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s %s sourcecode input", argv[0], argv[1]);
}
else {
char source[] = "This is an example.";
int i;
for (i = 0; i < sizeof(source); i++) {
printf("%c", source[i]);
}
}
getchar();
return 0;
}
This does also NOT work:
char *source = "This is an example.";
int i;
for (i = 0; i < strlen(source); i++){
printf("%c", source[i]);
}
I get the error
Unhandled exception at 0x5bf714cf (msvcr100d.dll) in Test.exe: 0xC0000005: Access violation while reading at position 0x00000054.
(loosely translated from german)
So what's wrong with my code?
You want:
for (i = 0; i < strlen(source); i++) {
sizeof gives you the size of the pointer, not the string. However, it would have worked if you had declared the pointer as an array:
char source[] = "This is an example.";
but if you pass the array to function, that too will decay to a pointer. For strings it's best to always use strlen. And note what others have said about changing printf to use %c. And also, taking mmyers comments on efficiency into account, it would be better to move the call to strlen out of the loop:
int len = strlen(source);
for (i = 0; i < len; i++) {
or rewrite the loop:
for (i = 0; source[i] != 0; i++) {
One common idiom is:
char* c = source;
while (*c) putchar(*c++);
A few notes:
In C, strings are null-terminated. You iterate while the read character is not the null character.
*c++ increments c and returns the dereferenced old value of c.
printf("%s") prints a null-terminated string, not a char. This is the cause of your access violation.
Rather than use strlen as suggested above, you can just check for the NULL character:
#include <stdio.h>
int main(int argc, char *argv[])
{
const char *const pszSource = "This is an example.";
const char *pszChar = pszSource;
while (pszChar != NULL && *pszChar != '\0')
{
printf("%s", *pszChar);
++pszChar;
}
getchar();
return 0;
}
An optimized approach:
for (char character = *string; character != '\0'; character = *++string)
{
putchar(character); // Do something with character.
}
Most C strings are null-terminated, meaning that as soon as the character becomes a '\0' the loop should stop. The *++string is moving the pointer one byte, then dereferencing it, and the loop repeats.
The reason why this is more efficient than strlen() is because strlen already loops through the string to find the length, so you would effectively be looping twice (one more time than needed) with strlen().
sizeof(source) returns the number of bytes required by the pointer char*. You should replace it with strlen(source) which will be the length of the string you're trying to display.
Also, you should probably replace printf("%s",source[i]) with printf("%c",source[i]) since you're displaying a character.
sizeof() includes the terminating null character. You should use strlen() (but put the call outside the loop and save it in a variable), but that's probably not what's causing the exception.
you should use "%c", not "%s" in printf - you are printing a character, not a string.
This should work
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]){
char *source = "This is an example.";
int length = (int)strlen(source); //sizeof(source)=sizeof(char *) = 4 on a 32 bit implementation
for (int i = 0; i < length; i++)
{
printf("%c", source[i]);
}
}
The last index of a C-String is always the integer value 0, hence the phrase "null terminated string". Since integer 0 is the same as the Boolean value false in C, you can use that to make a simple while clause for your for loop. When it hits the last index, it will find a zero and equate that to false, ending the for loop.
for(int i = 0; string[i]; i++) { printf("Char at position %d is %c\n", i, string[i]); }
sizeof(source) is returning to you the size of a char*, not the length of the string. You should be using strlen(source), and you should move that out of the loop, or else you'll be recalculating the size of the string every loop.
By printing with the %s format modifier, printf is looking for a char*, but you're actually passing a char. You should use the %c modifier.
Just change sizeof with strlen.
Like this:
char *source = "This is an example.";
int i;
for (i = 0; i < strlen(source); i++){
printf("%c", source[i]);
}
This is 11 years old but relevant to someone who is learning C. I don't understand why we have all this discussion and disagreement about something so fundamental. A string literal in C, I.E. "Text between quotes" has an implicit null terminator after the last character. Don't let the name confuse you. The null terminator is equal to numeric 0. Its purpose is exactly what OP needs it for:
char source[] = "This is an example.";
for (int i = 0; source[i]; i++)
printf("%c", source[i]);
A char in C is an 8-bit integer with the numeric ASCII value of the corresponding character. That means source[i] is a positive integer until char[19], which is the null terminator after the final '.' The null character is ASCII 0. This is where the loop terminates. The loop iterates through every character with no regard for the length of the array.
Replace sizeof with strlen and it should work.
sizeof(source) returns sizeof a pointer as source is declared as char *.
Correct way to use it is strlen(source).
Next:
printf("%s",source[i]);
expects string. i.e %s expects string but you are iterating in a loop to print each character. Hence use %c.
However your way of accessing(iterating) a string using the index i is correct and hence there are no other issues in it.
You need a pointer to the first char to have an ANSI string.
printf("%s", source + i);
will do the job
Plus, of course you should have meant strlen(source), not sizeof(source).

Resources