How would you be able to count word lengths and output their occurrences from a string using gets() or fgets()? For example, here is code doing so but using getchar()below. I think writing it in gets() would make it easier to incorporate all of the delimiters in the program rather than having to manually set if statements for each one of those would it not?
#include <string.h>
#include <ctype.h>
const char delim[] = ", . - !*()&^%$##<> ? []{}\\ / \"";
#define SIZE 100
int main(void){
int length[SIZE] = { 0 };
int name[SIZE];
int i = 0, ch, word_len = 0;
int count = 0;
printf("enter sentence: ");
while (1){
ch = getchar();
if (isalpha(ch)){
++word_len;
}
else if (ch == ' ' || ch == '.'){
if (word_len)
length[word_len - 1]++;//-1: to 0 origin
if (ch == '.')
break;
word_len = 0;
}
}
printf("Word Length \tCount \n");
for (i = 0; i<sizeof(length) / sizeof(*length); ++i){
if (length[i])
printf(" %d \t\t%d\n", i + 1, length[i]);
}
return 0;
}
You can build your custom delimiter detection function.
// globals
const char *delim = " .,;:!?\n\0";
const int n_delim = 9;
int is_delim(int c)
{
register int i;
for (i = 0; i < n_delim; i++)
if (c == delim[i]) return 1;
return 0;
}
This function will return 1 every time it can match c with delim. So you can use it like this:
fgets(buffer, 200, stdin);
for (i = 0; i < strlen(buffer); i++) {
if (is_delim(buffer[i])) {
wl[words++] = length;
length = 0;
continue;
}
length++;
}
I'm assuming you're familiar with the fgets function.
You basically will loop through your buffer, making comparisons with each character. Every loop iteration you check if the current character is a word delimiter, if it is, you save the current length and set length=0 for a new word, and at every iteration you increment the length.
You'll need to come up with a way of either not inserting the zero length values due to double delimiters or just ignore them when you're printing the results.
Basically you want to split a string into words, based on some delimiters, and compute their length. The C standard library provides the strtok function, which does exactly what you need: it splits the given string into multiple tokens.
Related
I'm having trouble with trying to manipulate 2d dynamic arrays in C. What I want to do is to store a char string in every row of the the 2d array then perform a check to see if the string contains a certain character, if so remove all occurrences then shift over the empty positions. What's actually happening is I get an exit status 1.
More about the problem, for example if I have
Enter string 1: testing
Enter string 2: apple
Enter string 3: banana
I would want the output to become
What letter? a // ask what character to search for and remove all occurences
testing
pple
bnn
Here is my full code:
#include <stdio.h>
#include <stdlib.h>
void removeOccurences2(char** letters, int strs, int size, char letter){
// Get size of array
// Shift amount says how many of the letter that we have removed so far.
int shiftAmt = 0;
// Shift array says how much we should shift each element at the end
int shiftArray[strs][size];
// The first loop to remove letters and put things the shift amount in the array
int i,j;
for(i=0;i < strs; i++){
for(j = 0; j < size - 1; j++) {
if (letters[i][j] == '\0'){
break;
}
else {
// If the letter matches
if(letter == letters[i][j]){
// Set to null terminator
letters[i][j] = '\0';
// Increase Shift amount
shiftAmt++;
// Set shift amount for this position to be 0
shiftArray[i][j] = 0;
}else{
// Set the shift amount for this letter to be equal to the current shift amount
shiftArray[i][j] = shiftAmt;
}
}
}
}
// Loop back through and shift each index the required amount
for(i = 0; i < strs; i++){
for(j = 0; j < size - 1; j++) {
// If the shift amount for this index is 0 don't do anything
if(shiftArray[i][j] == 0) continue;
// Otherwise swap
letters[i][j - shiftArray[i][j]] = letters[i][j];
letters[i][j] = '\0';
}
//now print the new string
printf("%s", letters[i]);
}
return;
}
int main() {
int strs;
char** array2;
int size;
int cnt;
int c;
char letter;
printf("How many strings do you want to enter?\n");
scanf("%d", &strs);
printf("What is the max size of the strings?\n");
scanf("%d", &size);
array2 = malloc(sizeof(char*)*strs);
cnt = 0;
while (cnt < strs) {
c = 0;
printf("Enter string %d:\n", cnt + 1);
array2[cnt] = malloc(sizeof(char)*size);
scanf("%s", array2[cnt]);
cnt += 1;
}
printf("What letter?\n");
scanf(" %c", &letter);
removeOccurences2(array2,strs,size,letter);
}
Thanks in advance!
You can remove letters from a string in place, because you can only shorten the string.
The code could simply be:
void removeOccurences2(char** letters, int strs, int size, char letter){
int i,j,k;
// loop over the array of strings
for(i=0;i < strs; i++){
// loop per string
for(j = 0, k=0; j < size; j++) {
// stop on the first null character
if (letters[i][j] == '\0'){
letters[i][k] = 0;
break;
}
// If the letter does not match, keep the letter
if(letter != letters[i][j]){
letters[i][k++] = letters[i][j];
}
}
//now print the new string
printf("%s\n", letters[i]);
}
return;
}
But you should free all the allocated arrays before returning to environment, and explicitely return 0 at the end of main.
Well, there are several issues on your program, basically you are getting segmentation fault error because you are accessing invalid memory which isn't allocated by your program. Here are some issues I found:
shiftAmt isn't reset after processing/checking each string which lead to incorrect value of shiftArray.
Values of shiftArray only set as expected for length of string but after that (values from from length of each string to size) are random numbers.
The logic to delete occurrence character is incorrect - you need to shift the whole string after the occurrence character to the left not just manipulating a single character like what you are doing.
1 & 2 cause the segmentation fault error (crash the program) because it causes this line letters[i][j - shiftArray[i][j]] = letters[i][j]; access to unexpected memory. You can take a look at my edited version of your removeOccurences2 method for reference:
int removeOccurences2(char* string, char letter) {
if(!string) return -1;
int i = 0;
while (*(string+i) != '\0') {
if (*(string+i) == letter) {
memmove(string + i, string + i + 1, strlen(string + i + 1));
string[strlen(string) - 1] = '\0'; // delete last character
}
i++;
}
return 0;
}
It's just an example and there is still some flaw in its logics waiting for you to complete. Hint: try the case: "bananaaaa123"
Happy coding!
"...if the string contains a certain character, if so remove all occurrences then shift over the empty positions."
The original string can be edited in place by incrementing two pointers initially containing the same content. The following illustrates.:
void remove_all_chars(char* str, char c)
{
char *pr = str://pointer read
char *pw = str;//pointer write
while(*pr)
{
*pw = *pr++;
pw += (*pw != c);//increment pw only if current position == c
}
*pw = '\0';//terminate to mark last position of modified string
}
This is the cleanest, simplest form I have seen for doing this task. Credit goes to this answer.
I wrote a program to find the longest word in a string and print the number of letters in the longest word. But the code is not printing. I analyzed the program many times but I could not find the solution.
#include <stdio.h>
#include <string.h>
int main() {
char string[100] = "Hello Kurnool";
int i = 0, letters = 0, longest = 0;
start:
for (; string[i] !=' '; i++) {
letters++;
}
if (letters >= longest)
longest = letters;
if (string[i] == ' ') {
letters = 0;
i++;
goto start;
}
printf("%d", longest);
return 0;
}
Using goto is highly discouraged. You should convert your code to use a loop.
The main problem in your code is you do not stop the scan when you reach the end of the string.
Here is a modified version:
#include <stdio.h>
int main() {
char string[100] = "Hello Kurnool";
int i, letters, longest = 0, longest_pos = 0;
for (i = 0; string[i] != '\0'; i++) {
for (letters = 0; string[i] != '\0' && string[i] != ' '; i++) {
letters++;
}
if (letters > longest) {
longest = letters;
longest_pos = i - longest;
}
}
printf("longest word: %d letters, '%.*s'\n",
longest, longest, string + longest_pos);
return 0;
}
Note that the implementation can be simplified into a single loop:
#include <stdio.h>
int main() {
char string[100] = "Hello Kurnool";
int i, start = 0, longest = 0, longest_pos = 0;
for (i = 0; string[i] != '\0'; i++) {
if (string[i] == ' ') {
start = i + 1;
} else {
if (i - start > longest) {
longest = i - start;
longest_pos = start;
}
}
}
printf("longest word: %d letters, '%.*s'\n",
longest, longest, string + longest_pos);
return 0;
}
Below is my approach. You should use C's string manipulation functions. This is the correct way to deal with strings in C.
In the code below, first I acquire the required bytes to store the input string in heap. Then I use strtok to split the string into tokens based on a delemeter and get the length of each sub string. Finally I free the space that I have allocated with malloc.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define phrase "Hello Kurnool"
int main()
{
char* string = malloc(strlen(phrase)+1);
strcpy(string,phrase);
int longest=0;
char *token;
char delimeter[2] = " ";
/* get the first token */
token = strtok(string, delimeter);
/* walk through other tokens */
while( token != NULL ) {
printf( " %s\n", token );
if(longest < strlen(token)){
longest = strlen(token);
}
token = strtok(NULL, delimeter);
}
printf("%d",longest);
free(string);
return 0;
}
People say - dont use goto but there is nothing inherently wrong with goto. Only thing is if goto is not used judiciously, it makes code more difficult to understand and maintain. For example, the way you have used it in your program ( instead of goto, a loop is perfect fit in such cases). Check this:
To use goto or not?
What is wrong with using goto?
Coming to your code, the for loop condition does not have check for terminating null character
for (; string[i] !=' '; i++) {
Hence it will not stop at the end of string.
To find the number of letters in longest word of string, you can do:
#include <stdio.h>
#include <string.h>
int main() {
char string[100] = "Hello Kurnool";
int i, letters = 0, longest = 0;
for (i = 0; string[i] != '\0'; i++) {
if (string[i] != ' ') {
letters++;
if (letters > longest) {
longest = letters;
}
} else {
letters = 0;
}
}
printf("longest : %d\n", longest);
return 0;
}
First of all,Please avoid using Goto, it is not a good practice.
Secondly, your loop will run infinite times when it iterates the second time because:
for(;string[i]!=' ';i++) // Here String[i] will never be equal to ' ' As there is no white space after your last word.
You can never expect what might be going wrong with your program if you are using
goto statement
which is never advisable to use rather it's bad programming if you use it. Secondly it looks like you are stuck in an infinite loop so her is a solution to your problem:
#include<stdio.h>
#include<string.h>
void main()
{
char s[1000];
scanf("%s",s);
int i=0;
int letters;
int longest=0;
while(s[i]!=NULL)
{
if(s[i]==' ')
{
if(longest>=letters)
{longest=letters;}
letters=0;
}
else
{letters++;}
}
printf("%d\n",longest);
}
So, what I have done is assuming a string s which is the input given by the user. You itterate through s till the last input given by the user after which it encounters a NULL character. Now you are searching for the length of the longest word, so you create a variable letters for counting the no. of letters in each word of the string. And if the string s encounters a space indicating the end of a word, then you check if the variable longest is greater than or less than the word count. And again you initialize letters to 0, so that it can start counting the next word from 0 again.So, by this method at the end i.e. after the while loop terminates we get our required output which is stored in the variable longest.
So, I guess this will print the no. of letters in the longest word.
this is my first post in this forum so please be patient.
I need to make a short programm, where the user can enter 2 strings which should be attached afterwards.
I already got this code below (I am not allowed to use other "includes").
What I need to know is: How can I deny any spaces which the user will enter?
Example: 1. String "Hello " | 2. String "World" Result should be "HelloWorld" instead of "Hello World".
#include <stdio.h>
void main()
{
char eingabe1[100];
char eingabe2[100];
int i = 0;
int j = 0;
printf("Gib zwei Wörter ein, die aneinander angehängt werden sollen\n");
printf("1. Zeichenkette: ");
gets(eingabe1);
printf("\n");
printf("2. Zeichenkette: ");
gets(eingabe2);
printf("\n");
while (eingabe1[i] != '\0')
{
i++;
}
while (eingabe2[j] != '\0')
{
eingabe1[i++] = eingabe2[j++];
}
eingabe1[i] = '\0';
printf("Nach Verketten: ");
puts(eingabe1);
}
You have to filter out the spaces as you copy your strings.
You have two string indices, i for the first string and and j for the second string. You could make better use of these indices if you used i for the reading position (of both strings subsequently; you can "reuse" loop counters in independent loops) and j for the writing position.
Here's how. Note that the code attempts to prevent buffer overflow by only adding characters if there is space in the string. This check needs only to be done when copying the second string, because j <= i when you process the first string.
#include <stdio.h>
int main()
{
char str1[100] = "The quick brown fox jumps over ";
char str2[100] = "my big sphinx of quartz";
int i = 0;
int j = 0;
while (str1[i] != '\0') {
if (str1[i] != ' ') str1[j++] = str1[i];
i++;
}
i = 0;
while (str2[i] != '\0') {
if (str2[i] != ' ' && j + 1 < sizeof(str1)) str1[j++] = str2[i];
i++;
}
str1[j] = '\0';
printf("'%s'\n", str1);
return 0;
}
In addition to avoiding spaces between your two words, you also have to avoid the newline ('\n') character placed in the input buffer by the user pressing Enter. You can do that with a simple test after you have read the line with fgets() NOT gets(). gets() is no longer part of the standard C library and should not be used due to insecurity reasons. Plus fgets provides simple length control over the number of characters a user may enter at any time.
Below, you run into trouble when you read eingabe1. After the read, eingabe1 contains a '\n' character at its end. (as it would using any of the line-oriented input functions (e.g. getline(), fgets(), etc) To handle the newline, you can simply compare its length minus '1' after you loop over the string to find the nul character. e.g.:
if (eingabe1[i-1] == '\n') i--; /* remove trailing '\n', update i */
By simply reducing the index 'i', this will guarantee that the concatenation with eingabe2 will not have any spaces or newline characters between the words.
Putting the pieces together, and using fgets in place of the insecure gets, after #define MAX 100'ing a constant to prevent hardcoding your array indexes, you could come up with something similar to:
#include <stdio.h>
#define MAX 100
int main (void)
{
char eingabe1[MAX] = {0};
char eingabe2[MAX] = {0};
int i = 0;
int j = 0;
printf("Gib zwei Wörter ein, die aneinander angehängt werden sollen\n");
printf("1. Zeichenkette: ");
/* do NOT use gets - it is no longer part of the C library */
fgets(eingabe1, MAX, stdin);
putchar ('\n');
printf("2. Zeichenkette: ");
/* do NOT use gets - it is no longer part of the C library */
fgets(eingabe2, MAX, stdin);
putchar ('\n');
while (eingabe1[i]) i++; /* set i (index) to terminating nul */
if (i > 0) {
if (eingabe1[i-1] == '\n') i--; /* remove trailing '\n' */
while (i && eingabe1[i-1] == ' ') /* remove trailing ' ' */
i--;
}
while (eingabe2[j]) { /* concatenate string - no spaces */
eingabe1[i++] = eingabe2[j++];
}
eingabe1[i] = 0; /* nul-terminate eingabe1 */
printf("Nach Verketten: %s\n", eingabe1);
return 0;
}
Output
$ ./bin/strcatsimple
Gib zwei Wörter ein, die aneinander angehängt werden sollen
1. Zeichenkette: Lars
2. Zeichenkette: Kenitsche
Nach Verketten: LarsKenitsche
Let me know if you have any further questions. I have highlighted the changes with comments above.
/**
return: the new len of the string;
*/
int removeChar(char* string, char c) {
int i, j;
int len = strlen(string)+1; // +1 to include '\0'
for(i = 0, j = 0 ; i < len ; i++){
if( string[i] == c )
continue; // avoid incrementing j and copying c
string[ j ] = string[ i ]; // shift characters
j++;
}
return j-1; // do not count '\0';
}
int main(){
char str1[] = "sky is flat ";
char str2[100] = "earth is small ";
strcat( str2, str1 );
printf("with spaces:\n\t'%s'\n", str2) ;
removeChar(str2, ' ');
printf("without spaces:\n\t'%s'\n", str2 );
}
/**
BONUS: this will remove many characters at once, eg "\n \r\t"
return: the new len of the string;
*/
int removeChars(char* string, char *chars) {
int i, j;
int len = strlen(string);
for(i = 0, j = 0 ; i < len ; i++){
if( strchr(chars,string[i]) )
continue; // avoid incrementing j and copying c
string[ j ] = string[ i ]; // shift characters
j++;
}
string[ j ]=0;
return j;
}
Thank you everyone for all the answers.
I got the solution now.
I read some advices from you and will try to remember for the future.
See the code below:
(Excuse me for the strange names for the variables, I use german words)
A few notices:
I am not allowed to use library functions
I am not allowed to use fgets for some reasons as a trainee
#include <stdio.h>
void main()
{
char eingabe1[100];
char eingabe2[100];
int i = 0;
int j = 0;
printf("gib zwei wörter ein, die aneinander angehängt werden sollen\n");
printf("1. zeichenkette: ");
gets(eingabe1);
printf("\n");
printf("2. zeichenkette: ");
gets(eingabe2);
printf("\n");
//Attach Strings
while (eingabe1[i] != '\0')
{
i++;
}
while (eingabe2[j] != '\0')
{
eingabe1[i++] = eingabe2[j++];
}
//Remove Space
eingabe1[i] = '\0';
i = 0;
j = 0;
while (eingabe1[i] != '\0')
{
if (eingabe1[i] != 32)
{
eingabe2[j++] = eingabe1[i];
}
i++;
}
eingabe2[j] = '\0';
printf("Nach verketten: ");
puts(eingabe2);
}
Sounds like homework to me.
I just wanted to mention that you probably shouldn't use sizeof() on strings these days because there may be multibyte characters in there. Use strlen() instead. The only time sizeof() would be appropriate is if you're going to malloc() a certain number of bytes to store it.
I write little loops fairly often to do low level text stuff one character at a time, just be aware that strings in C usually have a 0 byte at the end. You have to expect to encounter one and be sure you put one on the output. Space is 0x20 or decimal 32 or ' ', it's just another character.
I am trying to write a simple C program to output the length of words and output their frequencies. For example, if the user inputs "hey" my program would output Length of word: 3 Occurrences 1, and so on with a larger string inputted. I just cannot seem to loop it properly. I thought of setting both counters when a delimiter is seen to count both the length of the word at the time and its occurrence but I have not found a way for it to work. How can I fix my loop? My code is below. I'd appreciate any help. I should include my program only runs correctly for one word inputted but not a whole sentence or multiple sentences.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
const char delim[] = ", . - !*()&^%$##<> ? []{}\\ / \"";
const int n_delim = 31;
#define SIZE 1000
int is_delim(int c);
int main(){
char string[SIZE];
int wordlength = 0, wl[SIZE];
int word = 0, i;
printf("Enter your input string:");
fgets(string, SIZE, stdin);
string[strlen(string) - 1] = '\0';
printf("Word Length\tCount\n");
int seen = 0;
int l;
for (i = 0; i < strlen(string); i++){
if (is_delim(string[i])){
wl[word++] = wordlength;
l = wordlength;
seen++;
printf("%d\t\t%d\n", l, seen);
wordlength = 0;
}
wordlength++;
}
return 0;
}
int is_delim(int c){
register int i;
for (i = 0; i < n_delim; i++)
if (c == delim[i]) return 1;
return 0;
}
The trick is that wl[n] holds the count of words
of length n. Also, you don't need to keep calling strlen()
on every iteration, just check for the zero byte at the end.
The optimizer will do this for you, if you enable it.
The odd-looking for(;1;) is so that the loop counts
the final word, which is terminated by the zero byte.
memset(wl,0,sizeof(wl));
for(wordStart=maxLength=i=0;1;i++) {
if(is_delim(string[i]) || string[i]==0) {
int wordLength= i-wordStart;
if(wordLength>0)
wl[wordLength]++;
if(wordLength>maxLength)
maxLength= wordLength;
wordStart= i+1;
}
if(string[i]==0)
break;
}
for(i=1;i<=maxLength;i++) {
if(wl[i]>0) {
printf("%d words of length %d.\n",wl[i],i);
}
}
You really should use strtok for this. Right now, you never compare the last string with the current one so you can't tell them apart. You can use strcmp for this. Finally instead of manually testing the length of the string you should use strlen. Here is how your loop could look like
int seen = 0;
pch = strtok(string, delim);
last = pch;
while(pch != NULL) {
if(strcmp(last, pch) != 0) {
printf("%s:\t%d\t\t%d\n", last, (int)strlen(last), seen);
seen = 1;
}else {
seen++;
}
last = pch;
pch = strtok(NULL, delim);
}
printf("%s:\t%d\t\t%d\n", last, (int)strlen(last), seen);
Note, you should set the variable seen to 0 before the loop.
I am writing C program that reads input from the standard input a line of characters.Then output the line of characters in reverse order.
it doesn't print reversed array, instead it prints the regular array.
Can anyone help me?
What am I doing wrong?
main()
{
int count;
int MAX_SIZE = 20;
char c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
while(c != EOF)
{
count = 0;
c = getchar();
arr[count++] = c;
getReverse(revArr, arr);
printf("%s", revArr);
if (c == '\n')
{
printf("\n");
count = 0;
}
}
}
void getReverse(char dest[], char src[])
{
int i, j, n = sizeof(src);
for (i = n - 1, j = 0; i >= 0; i--)
{
j = 0;
dest[j] = src[i];
j++;
}
}
You have quite a few problems in there. The first is that there is no prototype in scope for getReverse() when you use it in main(). You should either provide a prototype or just move getReverse() to above main() so that main() knows about it.
The second is the fact that you're trying to reverse the string after every character being entered, and that your input method is not quite right (it checks an indeterminate c before ever getting a character). It would be better as something like this:
count = 0;
c = getchar();
while (c != EOF) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
That will get you a proper C string albeit one with a newline on the end, and even possibly a multi-line string, which doesn't match your specs ("reads input from the standard input a line of characters"). If you want a newline or file-end to terminate input, you can use this instead:
count = 0;
c = getchar();
while ((c != '\n') && (c != EOF)) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
And, on top of that, c should actually be an int, not a char, because it has to be able to store every possible character plus the EOF marker.
Your getReverse() function also has problems, mainly due to the fact it's not putting an end-string marker at the end of the array but also because it uses the wrong size (sizeof rather than strlen) and because it appears to re-initialise j every time through the loop. In any case, it can be greatly simplified:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0) {
dest[j] = src[i];
j++;
i--;
}
dest[j] = '\0';
}
or, once you're a proficient coder:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0)
dest[j++] = src[i--];
dest[j] = '\0';
}
If you need a main program which gives you reversed characters for each line, you can do that with something like this:
int main (void) {
int count;
int MAX_SIZE = 20;
int c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
c = getchar();
count = 0;
while(c != EOF) {
if (c != '\n') {
arr[count++] = c;
c = getchar();
continue;
}
arr[count] = '\0';
getReverse(revArr, arr);
printf("'%s' => '%s'\n", arr, revArr);
count = 0;
c = getchar();
}
return 0;
}
which, on a sample run, shows:
pax> ./testprog
hello
'hello' => 'olleh'
goodbye
'goodbye' => 'eybdoog'
a man a plan a canal panama
'a man a plan a canal panama' => 'amanap lanac a nalp a nam a'
Your 'count' variable goes to 0 every time the while loop runs.
Count is initialised to 0 everytime the loop is entered
you are sending the array with each character for reversal which is not a very bright thing to do but won't create problems. Rather, first store all the characters in the array and send it once to the getreverse function after the array is complete.
sizeof(src) will not give the number of characters. How about you send i after the loop was terminated in main as a parameter too. Ofcourse there are many ways and various function but since it seems like you are in the initial stages, you can try up strlen and other such functions.
you have initialised j to 0 in the for loop but again, specifying it INSIDE the loop will initialise the value everytime its run from the top hence j ends up not incrmenting. So remore the j=0 and i=0 from INSIDE the loop since you only need to get it initialised once.
check this out
#include <stdio.h>
#include <ctype.h>
void getReverse(char dest[], char src[], int count);
int main()
{
// *always* initialize variables
int count = 0;
const int MaxLen = 20; // max length string, leave upper case names for MACROS
const int MaxSize = MaxLen + 1; // add one for ending \0
int c = '\0';
char arr[MaxSize] = {0};
char revArr[MaxSize] = {0};
// first collect characters to be reversed
// note that input is buffered so user could enter more than MAX_SIZE
do
{
c = fgetc(stdin);
if ( c != EOF && (isalpha(c) || isdigit(c))) // only consider "proper" characters
{
arr[count++] = (char)c;
}
}
while(c != EOF && c != '\n' && count < MaxLen); // EOF or Newline or MaxLen
getReverse( revArr, arr, count );
printf("%s\n", revArr);
return 0;
}
void getReverse(char dest[], char src[], int count)
{
int i = count - 1;
int j = 0;
while ( i > -1 )
{
dest[j++] = src[i--];
}
}
Dealing with strings is a rich source of bugs in C, because even simple operations like copying and modifying require thinking about issues of allocation and storage. This problem though can be simplified considerably by thinking of the input and output not as strings but as streams of characters, and relying on recursion and local storage to handle all allocation.
The following is a complete program that will read one line of standard input and print its reverse to standard output, with the length of the input limited only by the growth of the stack:
int florb (int c) { return c == '\n' ? c : putchar(florb(getchar())), c; }
main() { florb('-'); }
..or check this
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
char *my_rev(const char *source);
int main(void)
{
char *stringA;
stringA = malloc(MAX); /* memory allocation for 100 characters */
if(stringA == NULL) /* if malloc returns NULL error msg is printed and program exits */
{
fprintf(stdout, "Out of memory error\n");
exit(1);
}
else
{
fprintf(stdout, "Type a string:\n");
fgets(stringA, MAX, stdin);
my_rev(stringA);
}
return 0;
}
char *my_rev(const char *source) /* const makes sure that function does not modify the value pointed to by source pointer */
{
int len = 0; /* first function calculates the length of the string */
while(*source != '\n') /* fgets preserves terminating newline, that's why \n is used instead of \0 */
{
len++;
*source++;
}
len--; /* length calculation includes newline, so length is subtracted by one */
*source--; /* pointer moved to point to last character instead of \n */
int b;
for(b = len; b >= 0; b--) /* for loop prints string in reverse order */
{
fprintf(stdout, "%c", *source);
len--;
*source--;
}
return;
}
Output looks like this:
Type a string:
writing about C programming
gnimmargorp C tuoba gnitirw