printf function won't print reversed string - string

I have to write a function which gets a string and then reverses it. I wrote this code, which gave me no compilation errors:
#include <stdio.h>
#include <string.h>
char *reverse(char *str);
int main(void){
char string[100];
printf("Insert the string to be inverted: ");
gets(string);
reverse(string);
printf("Inverted string is: %s\n", string);
}
char *reverse(char *str){
char h;
int i, j;
for(i=0, j=strlen(str); i<j; i++, j--){
h=str[i];
str[i]=str[j];
str[j]=h;
}
}
Only problem I get is that, apparently, printf won't print the reversed string. Can anyone help me?

The reversed string has the terminator \0 at position 0.

strlen(str) gives you the size of the string, i.e. the index of the terminating null character.
You don't want to swap the null terminator, so strlen(str) - 1 is the index of the last character you want to swap.
Therefore, j should start at strlen(str) - 1.

Related

How to parse a string into f64, and get the remainder of the string, like strtod?

In C++, strtod parses a prefix of a string into a double, and provides the remainder of the string. Example:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *end;
double d = strtod("1.5e3randomstuff", &end);
printf("%g - %s\n", d, end);
}
This outputs 1500 - randomstuff.
How can I achieve the same in Rust? The str::parse function errors on invalid characters and does not return the string remainder.

C function to remove instances of one char from a string

I did it right but it only works if the base string is one word:
#include <stdio.h>
void withoutString(char *new, char *base, char removee){
while(*base){
if(*base!=removee){
*new++=*base;}
base++;
}
*new='\0';
}
int main()
{
char b[16],n[16],r;
printf("Please enter string: ");
scanf(" %s", b);
printf("Which character do you want to remove? \n");
scanf(" %c",&r);
withoutString(n, b, r);
printf(" The new string is %s", n);
return 0;
}
How do I make it work for more words?
Read and understand the documentation of scanf. Good sources for documentation on the C standard functions are the C standard itself and POSIX.
You will then notice that scanf is not the best function to read a whole line, so look for fgets next.

If statements in my C code are doing the exact opposite of the conditions?

So i'm comparing two strings and my code is doing the exact opposite of what it should be doing. I can't switch up my printf statements because then that would also be wrong. If i input the first string that has length 5 and a second string with length 6, it will say that string 1 is GREATER than string 2 when it's the exact opposite.
Here is what I have:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char str1[100], str2[100];
printf("enter the first string :");
scanf("%s", &str1);
printf("enter the second string :");
scanf("%s", &str2);
if(strcmp(str1,str2)==0){
printf("the strings are equal\n");
}
else if(strcmp(str1,str2)<0){
printf("string 1 is less than string 2\n");
}
else{
printf("string 1 is greater than string 2\n");
}
return 0;
}
strcmp doesn't compare the lengths of strings. It compares characters until it founds two that are not the same, then returns a negative or positive number depending on which string had the character earlier in the alphabet. If one string runs out ("Hello" vs. "Hell") then the shorter one comes first. And if they are identical then the result is 0.
For example, "xyz" > "abcde" because x comes after a.
Strcmp compares the strings according to the alphabetical order.
To compare the length of the strings, just replace strcmp() with strlen().

Program keeps giving me the "core dump", though i can't find why

So, i wrote this program which receives as input a string, which consists of surname and name, written like this: "james:lebron". The program should copy surname in the surname variable of the struct, same goes for the name. No compilation errors, just the core dump error. Somebody can please explain me why?
#include <stdio.h>
#include <string.h>
struct author{
char *name;
char *surname;
};
typedef struct author author_t;
author_t separate(char *string);
int main(void){
char *name_surname;
printf("Inserisci nome e cognome: ");
gets(name_surname);
separate(name_surname);
}
author_t separate(char *string){
int i, n=0;
author_t temp;
for(i=0; i<(strlen(string)-1); i++){
while(string[i]!=':')
n++;
strncpy(temp.surname, string, n);
strncpy(temp.name, &string[n+2], (strlen(string)-n-2));
}
return(temp);
}
off teh top of my head Id say incrementing n is not a good idea as n i steh number of items to copy not the position in the string.
struct author{
char *name;
char *surname;
};
....
int i, n=0;
author_t temp;
for(i=0; i<(strlen(string)-1); i++){
while(string[i]!=':')
n++;
strncpy(temp.surname, string, n);
strncpy(temp.name, &string[n+2], (strlen(string)-n-2));
}
You cannot copy into tmp.surname or temp.name, as you did not reserve any memory yet. (Note that strncpy does not reserve memory, it just copies.) char *name only reserves space for a pointer, not the actual string. User char name[30] or so, or assign memory later like this:
author_t auth;
auth.name = (char *) malloc(30);
(same for surname, of course)

Parsing a string with varying number of whitespace characters in C

I'm pretty new to C, and trying to write a function that will parse a string such as:
"This (5 spaces here) is (1 space
here) a (2 spaces here) string."
The function header would have a pointer to the string passed in such as:
bool Class::Parse( unsigned char* string )
In the end I'd like to parse each word regardless of the number of spaces between words, and store the words in a dynamic array.
Forgive the silly questions...
But what would be the most efficient way to do this if I am iterating over each character? Is that how strings are stored? So if I was to start iterating with:
while ( (*string) != '\0' ) {
--print *string here--
}
Would that be printing out
T
h
i... etc?
Thank you very much for any help you can provide.
from http://www.cplusplus.com/reference/clibrary/cstring/strtok/
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-"); /* split the string on these delimiters into "tokens" */
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-"); /* split the string on these delimiters into "tokens" */
}
return 0;
}
Splitting string "- This, a sample string." into tokens:
This
a
sample
string
First of all, C does not have classes, so in a C program you would probably define your function with a prototype more like one of the following:
char ** my_prog_parse(char * string) {
/* (returns a malloc'd array of pointers into the original string, which has had
* \0 added throughout ) */
char ** my_prog_parse(const char * string) {
/* (returns a malloc'd NULL-terminated array of pointers to malloc'd strings) */
void my_prog_parse(const char * string, char buf, size_t bufsiz,
char ** strings, size_t nstrings)
/* builds a NULL-terminated array of pointers into buf, all memory
provided by caller) */
However, it is perfectly possible to use C-style strings in C++...
You could write your loop as
while (*string) { ... ; string++; }
and it will compile to exactly the same assembler on a modern optimizing compiler. yes, that is a correct way to iterate through a C-style string.
Take a look at the functions strtok, strchr, strstr, and strspn... one of them may help you build a solution.
I wouldn't do any non-trivial parsing in C, it's too laborious, the language is not suitable for that. But if you mean C++, and it looks like you do, since you wrote Class::Parse, then writing recursive descent parsers is pretty easy, and you don't need to reinvent the wheel. You can take Spirit for example, or AXE, if you compiler supports C++0x. For example, your parser in AXE can be written in few lines:
// assuming you have 0-terminated string
bool Class::Parse(const char* str)
{
auto space = r_lit(' ');
auto string_rule = "This" & r_many(space, 5) & space & 'a' & r_many(space, 2)
& "string" & r_end();
return string_rule(str, str + strlen(str)).matched;
}

Resources