The issue is detecting '\n' when I loop through my array. It works once as
shown in the comments, but it does not work after. The goal of this program is to take input from the terminal and put it into an array. The array should not contain any '\n'. Any help is appreciated, Thanks
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// 1. Function must take input and place in array whilst making sure it does not overflow
// 2. Must return null if end of stdi is reached
// 3. Must ensure that it does not contain delimeter \n
// Tests:
// a) empty string
// b) string longer than buffer
// c) what happens when you press ctrl-d
char read_line(char *buf, size_t sz) {
while(fgets(buf + strlen(buf), sz, stdin)){
if (strlen(buf) < sz) {
if(buf[strlen(buf)-1] == '\n' ){
// IT GET'S DETECTED HERE WHEN THE ENTER
// BUTTON
// IS PRESSED BUT ...
break;
}
}
}
// WHEN I LOOP THROUGH THE ARRAY IT GETS DETECTED AS SINGLE CHARS; '\'
// AND 'n' DISTINCTLY
for(int i = 0; i < strlen(buf)-1; ++i){
if(buf[i] == '\n'){
printf("present");
} else {
printf("x");
}
}
return NULL;
}
int main(int argc, char *argv[]){
char arra[20];
size_t sz = sizeof(arra);
memset(arra, 0, sz);
printf("Enter command: \n");
read_line(arra, sz);
// Print elements in array
printf("Printing out array: \n");
for(int i = 0; i < strlen(arra); ++i){
char c = arra[i];
printf("%c", c);
}
}
You appear to be entering something like the keystrokes hello\nENTER.
The entry of the two distinct characters \ and n are exactly that, two distinct characters. That is vastly different to the single newline character which is represented in the source as \n.
In terms of what the buffer will hold, it'll be the string "hello\\n\n", where \\ is the \ character, n is an n, and \n is the newline.
If your intent is to detect the newline in the string, you'll need to process every character in the string. The loop:
for (int i = 0; i < strlen(buf) - 1; ++i) ...
will basically skip the last character, which is fine for ignoring trailing newline should it exist but, if you want to detect it, you'll need:
for (int i = 0; i < strlen(buf); ++i) ...
suggest replacing:
for(int i = 0; i < strlen(buf)-1; ++i){
if(buf[i] == '\n'){
printf("present");
} else {
printf("x");
}
with:
if( strchr( buf, '\n' ) )
{
puts( "present" );
}
else
{
puts( "x" );
}
Related
I'm going to identify the difference between two string. I can't see what I'm missing here. The output from my code is correct by the sample. But when I test run it with other test, it fails. I can't see what the other tests are.
The input:
The first line of input contains an integer 1<= n <= 500, indicating the number of test cases that follow. Each test case is a pair of lines of the same length, 1 to 50 characters. Each string contains only letters (a-z,A-Z) or digits (0-9).
The Output:
For each test case, output the two lines in the order they appear in the input. Output a third line indicating similarities and differences as described above. Finally, output a blank line after each case.
Sample:
int main()
{
int n;
// scan the integer for number of test cases
if(scanf("%d", &n) != 1) {
return 1;
}
//Loop through the test cases
for (int i = 0; i < n; i++)
{
char string1[1024], string2[1024], output[50];
//Scan first and second string
if(scanf("%s", string1) != 1) {
return 1;
}
if(scanf("%s", string2) != 1) {
return 1;
}
//Loop through the strings and compare them
for (int i = 0; string1[i] != '\0' || string2[i] != '\0'; i++)
{
//Convert to lowercase
string1[i] = tolower(string1[i]);
string2[i] = tolower(string2[i]);
//Compare
if (string1[i] == string2[i])
{
output[i] = '.';
} else {
output[i] = '*';
}
}
//Print the strings and the output.
printf("%s\n%s\n%s\n", string1, string2, output);
if(i + 1 < n) {
printf("\n");
}
}
return 0;
}
Maybe the problem is that when you have an input string in upper case ("ABCD") you print it in lowercase in the output ("abcd")?
The output string is never terminated, a '\0' should be added after the loop is over, otherwise printf would read over to the memory filled by previous test cases if their inputs were longer.
There is no great sense to declare the variable n as having the signed integer type int. Declare it at least as having type unsigned int.
unsigned int n;
// scan the integer for number of test cases
if(scanf("%u", &n) != 1) {
return 1;
}
The three character array should be declared as having 51 elements
char string1[51], string2[51], output[51];
The calls of scanf will look like
//Scan first and second string
if(scanf(" %50s", string1) != 1) {
return 1;
}
if(scanf(" %50s", string2) != 1) {
return 1;
}
Also you need to check that the entered strings have the same length as for example
if( strlen( string1) != strlen( string2 ) ) {
return 1;
}
This for loop
for (int i = 0; string1[i] != '\0' || string2[i] != '\0'; i++)
can invoke undefined behavior if the lengths of strings are not equal each other. If you will include the above shown if statement then the for loop can look the following way
size_t i = 0;
for ( ; string1[i] != '\0'; i++ )
These statements change the original strings
//Convert to lowercase
string1[i] = tolower(string1[i]);
string2[i] = tolower(string2[i]);
that you should not do. Just compare corresponding characters like
if (string1[i] == string2[i])
{
output[i] = '.';
} else {
output[i] = '*';
}
If you want to compare characters independent on their cases then write
if ( tolower( ( unsigned char )string1[i] ) == tolower( ( unsigned char )string2[i] ) )
{
output[i] = '.';
} else {
output[i] = '*';
}
After the for loop write
output[i] = '\0';
tp form a string in the array output.
It seems this if statement
if(i + 1 < n) {
printf("\n");
}
is redundant. Just output the new line character '\n'
putchar( '\n' );
after each test case.
Needlessly complicated. And, if the source strings contain any whitespace characters, scanf won't satisfy your needs. Below is both simpler and more robust.
Challenge assures no line more than 50 (or 500???) chars, so use only two small arrays.
Challenge is to also output LF after EVERY test case, so suppressing final one with special code is wrong.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
void readAline( char *p, size_t n ) { // do or die
if( fgets( p, n, stdin ) == NULL )
exit( 1 );
}
int mmain() {
char buf[2][ 50 + 1 + 1 ]; // +2 = up to 50 + LF + '\0' from fgets()
readAline( buf[0], sizeof buf[0] );
int n = atoi( buf[0] );
while( n-- ) {
readAline( buf[0], sizeof buf[0] );
readAline( buf[1], sizeof buf[1] );
// can't be too careful when dealing with input
assert( strlen( buf[0] ) == strlen( buf[ 1 ] ) );
printf( "%s%s", buf[0], buf[1] ); // echo to stdout
// source data defined "up to 50 chars, so no test for '\0'
// recycle buf[0] for output
for( int i = 0; buf[0][i] != '\n'; i++ )
buf[0][i] = buf[0][i] == buf[1][i] ? '.' : '*';
puts( buf[0] ); // uses loaded LF and appended LF
}
return 0;
}
Demonstration
1
the cat sat on the mat
the fat cat in the vat
the cat sat on the mat // here is the echo
the fat cat in the vat
....*...*...*......*.. // here is the analysis
// blank line
I'm trying to create a program that checks if a given array/string is a palindrome or not and its not working. The program just prints "0" on every given array, even on palindromes.
int main()
{
char string[100]= {0};
char stringReverse[100]= {0};
int temp = 0;
int firstLetter = 0;
int lastLetter = 0;
printf("Please enter a word or a sentence: ");
fgets(string, 100, stdin);
strcpy(stringReverse , string); // This function copies the scanned array to a new array called "stringReverse"
firstLetter = 0;
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
// This while reverses the array and insert it to a new array called "stringReverse"
while(firstLetter < lastLetter)
{
temp = stringReverse[firstLetter];
stringReverse[firstLetter] = stringReverse[lastLetter];
stringReverse[lastLetter] = temp;
firstLetter++;
lastLetter--;
}
printf("%s %s", stringReverse, string);
if ( strcmp(stringReverse , string) == 0)
{
printf("1");
}
else
{
printf("0");
}
}
Lets say we implement a simple fun to do that
int check_palindrome (const char *s) {
int i,j;
for (i=0,j=strlen(s)-1 ; i<j ; ++i, --j) {
if (s[i] != s[j]) return 0; // Not palindrome
}
return 1; //Palindrome
}
I think this is far more simpler ;)
For the code posted in question:
Be aware of fgets(). It stops in the first '\n' or EOF and keeps the '\n' character.
So if you give radar for ex, the result string will be "radar\n", which doesn't match with "\nradar"
The Problem:
Let's say you enter the string RACECAR as input for your program and press enter, this puts a newline character or a '\n' in your buffer stream and this is also read as part of your string by fgets, and so your program effectively ends up checking if RACECAR\n is a palindrome, which it is not.
The Solution:
After you initialize lastLetter to strlen(string) - 1 check if the last character in your string (or the character at the lastLetter index is the newline character (\n) and if so, decrease lastLetter by one so that your program checks if the rest of your string (RACECAR) is a palindrome.
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
// Add these 2 lines to your code
// Checks if the last character of the string read by fgets is newline
if (string[lastLetter] == '\n')
lastLetter--;
fgets adds a '\n' at the end.
So if the user entered "aba", string contains "aba\n".
reverseString contains "\naba".
So it doesn't match.
After the fgets, add this code
int l = strlen(string) - 1;
string[l] = 0;
This will strip out the '\n' at the end before copying it to reverseString.
That aside, you can do this whole program inplace without the need of a second buffer or strcpy or strlen calls.
You have several issues in your code:
first you forgot the last closing brace };
then you forgot to remove the trailing \n (or maybe also \r under Windows) in string;
you don't need to revert the string into a new string; a one-pass check is enough:
Here is a working code:
#include <stdio.h>
#include <string.h>
int main()
{
char string[100]= {0};
int temp = 0;
int firstLetter = 0;
int lastLetter = 0;
printf("Please enter a word or a sentence: ");
fgets(string, 100, stdin);
firstLetter = 0;
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
while ((string[lastLetter]=='\n')||(string[lastLetter]=='\r')) {
lastLetter--;
}
// This while reverses the array and insert it to a new array called "stringReverse"
temp = 1;
while(firstLetter < lastLetter)
{
if (string[firstLetter] != string[lastLetter]) {
temp = 0;
break;
}
firstLetter++;
lastLetter--;
}
if ( temp )
{
printf("1");
}
else
{
printf("0");
}
}
You can do it by this simpleway also.
#include <stdio.h>
#include <string.h>
int main()
{
char string[10], revString[10];
printf("Enter string for reversing it...\n");
scanf("%s", string);
int stringLength = strlen(string);
for(int i = 0; string[i] != '\0'; i++, stringLength--)
{
revString[i] = string[stringLength - 1];
}
if(strcmp(string, revString) == 0)
printf("Given string is pelindrom\n");
else
printf("Given string is not pelindrom\n");
}
#include<stdio.h>
#include<string.h>`enter code here`
void fun(char *a);
int main ()
{
char p[100];
char *s=p;
printf("enter the string");
scanf("%[^\n]",s);
fun(s);
}
void fun(char *a)
{
if(*a && *a!='\n')
{
fun(a+1);
putchar(*a);
}
}
// use this approach better time complexity and easier work hope this helps
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'm writing a function called GetPattern() that will be used in my main() function.
Here's the context of how my main() uses the GetPattern() function.
int main(void)
{
int attempt=0, option=-1;
char pattern[SIZE+1], replacement[SIZE+1];
char name[20];
FILE *in, *out;
printf("Enter the pattern to find:");
GetPattern(pattern);
out = CreateFile();
Find(in, pattern, out);
fclose(in);
fclose(out);
return 0;
}
And here's my GetPattern() function:
void GetPattern(char *tmp)
{
// prompt the user for the pattern to be found/replaced
// note: any character, including ' ', maybe be part of the pattern
// we assume that the pattern has no more than 20 characters. If the user
// enters more than 20 characters, only the first 20 will be used.
int i;
for (i = 0; i < 20; i++) // iterate 20 times
{
scanf(" %c", &tmp[i]);
if (tmp[i] == '\n') // if user hits enter, break the loop
{
tmp[i] = '\0'; // insert '\0' at the end of the array
break;
}
else
tmp[i+1] = '\0'; // insert '\0' at the end of the array
}
printf("%s\n", tmp); // see what's in tmp[]
return;
}
The GetPattern() function works by itself; separate from the main() function, but when I put it into main, it exclusively accepts 20 characters and no less. Even when I hit ENTER (i.e., '\n'), the loop doesn't break--it keeps going.
Do you see anything obviously wrong with this code?
I think using getc() will help you.
for (i = 0; i < 20; i++) // iterate 20 times
{
//scanf(" %c", &tmp[i]);
tmp[i]=getc(stdin);/////
if (tmp[i] == '\n') // if user hits enter, break the loop
{
tmp[i] = '\0'; // insert '\0' at the end of the array
break;
}
else
tmp[i+1] = '\0'; // insert '\0' at the end of the array
}
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