Get suffixes in C - c

I'm trying to get the suffixes of an entered string, but i'm getting the prefixes how can I make to fix it?
The expected result for example with an entry string "Hello" is:
Hello
ello
ell
el
e
Now is returning:
Hello
Hell
Hel
He
H
Thanks
#include <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **suffix;
void panic(char *m) {
fprintf(stderr, "%s\n", m);
exit(0);
}
int main(int argc, char *argv[]) {
int n, i;
if (argc != 2)
panic("wrong parameters");
n = strlen(argv[1]);
suffix = (char **)malloc(n * sizeof(char *));
if (suffix == NULL)
error("Memoria no disponible");
for (i = 0; i < n; ++i) {
suffix[i] = (char *)malloc((n + 1 - i) * sizeof(char));
if (suffix[i] == NULL)
error("Memoria no disponible");
sprintf(suffix[i], "%s", argv[1]);
argv[1][n - 1 - i] = '\0';
}
for (i = 0; i < n; i++) {
printf("%d %s\n", i, suffix[i]);
}
return 0;
}

Just substitute these two statements
sprintf(suffix[i], "%s", argv[1]);
argv[1][n - 1 - i] = '\0';
for this one statement
sprintf(suffix[i], "%s", argv[1] + i );

Use Vlad from Moscow answer.
Something related you should now, only read argc and argv, never overwrite them. Although in theory you can do this, in practice it's both useless and dangerous.

Should always keep the code/logic as simple as you can.
The following proposed code can be halted with <ctrl-c> and/or EOF
#include <stdio.h>
#include <string.h>
int main( void )
{
char buffer[ 256 ];
// get the string
while( fgets( buffer, sizeof( buffer ), stdin ) )
{
//output string, dropping leading char at each loop iteration
size_t length = strlen( buffer );
for( size_t i=0; i<length; i++ )
{
printf( "%s\n", &buffer[i] );
}
}
}
here is a typical run of the program:
Note: the first line is from the user entering the string.
this is a string
this is a string
his is a string
is is a string
s is a string
is a string
is a string
s a string
a string
a string
string
string
tring
ring
ing
ng
g

Related

How to change one string to another with different sizes

I have a task to do. I have to work with strings. I will show you the input and output, because I think that will be clear what the task is.
Input: "aaa bbuvvvvo"
Output: "a$3 b$2uv$4o"
If there is the same symbols, I have to leave that symbol and then put dollar sign '$' and an integer of how many same signs was there. I am stuck on the spot, where I have to change string without losing any information.
I will leave my code here, it might help.
#include <stdio.h>
#include <string.h>
#define CAPACITY 255
#define MAX_NUMBER 10
void Output(char readFile[], char outputFile[], char string[]);
void changeString(char string[], char newString[]);
int main() {
char readFile[CAPACITY];
char outputFile[CAPACITY];
char string[CAPACITY];
// Input file's name
printf("Iveskite teksto failo varda: ");
scanf("%s", &readFile);
// Output file's name
printf("Iveskite teksto faila i kuri bus isvedamas atsakymas: ");
scanf("%s", &outputFile);
Output(readFile, outputFile, string);
return 0;
}
// Scanning file
void Output(char readFile[], char outputFile[], char string[])
{
char newString[CAPACITY];
FILE *input, *output;
input = fopen(readFile, "r");
while(fscanf(input, "%s", string) != EOF)
{
changeString(string, newString);
printf("%s\n", newString);
}
}
// Changing string to wanted string
void changeString(char string[], char newString[])
{
char number[MAX_NUMBER];
int symbols = 0;
int j;
for(int i = 0; string[i] != '\0'; ++i)
{
int temp = i;
newString[i] = string[i];
if(newString[i] == string[i + 1])
{
j = i;
while(string[j] == string[i])
{
++symbols;
++j;
}
// Changing int to char
sprintf(number, "%d", symbols);
newString[i + 1] = '$';
i += 2;
newString[i] = number[0];
symbols = 0;
}
}
}
I have tried to do that with function called changeString, but I get the wrong output all the time. Also the input I am getting is from .txt file.
EDIT: When I compiling this program right now, I get a$3 b$2v$4vo that output.
For starters this declaration in main
char string[CAPACITY];
does not make sense.
You should declare variables in scopes where they are used.
The variable string is used in the function Output where it is should be declared.
The function changeString should be declared like
void changeString( const char string[], char newString[]);
because the source string is not changed within the function.
Your function has several bugs.
For example it does not build a string in the array newString because it does not append the stored sequence in the array with the terminating zero character '\0'.
Secondly this increasing of the variable i
i += 2;
in general is invalid. You need to add to the variable i the number of repeated characters in the source string.
Or the number of repeated characters change greater than or equal to 10. In this case this statement
newString[i] = number[0];
will not produce correct result.
The function can be defined the following way as shown in the demonstration program below.
#include <stdio.h>
#define CAPACITY 255
void changeString( const char string[], char newString[] )
{
while ( *string )
{
*newString++ = *string;
size_t n = 1;
while (*++string == *( newString - 1 ) ) ++n;
if (n != 1)
{
*newString++ = '$';
int count = sprintf( newString, "%zu", n );
newString += count;
}
}
*newString = '\0';
}
int main( void )
{
char string[CAPACITY] = "aaa bbuvvvvo";
char newString[CAPACITY];
changeString( string, newString );
puts( newString );
}
The program output is
a$3 b$2uv$4o

Scanf an unknown amount of integers ,and stop the procedure while get an '\n'

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int a[100];
char mi[200];
char delims[] = "\040";
char * li;
fgets(mi,200,stdin);
li = mi;
li = strtok(li,delims);
a[0] = atoi(li);
for(int i=1;li!=NULL;i++)
{
li = strtok(NULL,delims);
a[i] = atoi(li);
}
return 0;
}
all the input were separate by space.
I wrote one,but it's so complex,so I wonder if there is an easier way.
That is pretty much how it needs to be done, although you have a small problem with your tokenizing loop: think about what will happen when there are no more tokens remaining. I would recommend using more meaningful variable names, to make code more self-documenting.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int values[100];
char linebuf[200];
char *token;
fgets(linebuf,sizeof(linebuf),stdin);
token = strtok(linebuf,' ');
for(int i = 0; token; i++) {
values[i] = atoi(token);
token = strtok(NULL,' ');
}
return 0;
}
If it were my code, I might prefer to use strtol instead of atoi, to be able to have some more error checking to screen out extraneous (non-numerical) characters.
If you use strtol instead of atoi, you don't need to use strtok. The function strtol will automatically discard all leading whitespace characters and will tell you the first character that it didn't convert, so you know where to continue.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NUMBERS 100
int main(void)
{
long numbers[MAX_NUMBERS];
char line[200];
char *p;
fgets( line, sizeof line, stdin );
p = line;
for ( int i = 0; i < MAX_NUMBERS; i++ )
{
long ret;
char *q;
numbers[i] = strtol( p, &q, 10 );
if ( p == q )
break;
p = q;
}
return 0;
}
If you do proper error checking, and print the result, the code will look like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define MAX_NUMBERS 100
int main(void)
{
long numbers[MAX_NUMBERS];
int num_converted;
char line[200];
char *p;
int i;
//attempt to read one line of input
if ( fgets( line, sizeof line, stdin ) == NULL )
{
fprintf( stderr, "error reading line!" );
exit( EXIT_FAILURE );
}
//make sure that entire line was read
if ( strchr( line, '\n' ) == NULL )
{
fprintf( stderr, "input line was too long!" );
exit( EXIT_FAILURE );
}
//begin at the start of the line
p = line;
for ( i = 0; i < MAX_NUMBERS; i++ )
{
long ret;
char *q;
//attempt to convert one number
errno = 0;
numbers[i] = strtol( p, &q, 10 );
//break loop if it was unable to convert another number
if ( p == q )
break;
//verify that the found number is not out of range
if ( errno == ERANGE )
{
fprintf( stderr, "number out of range!" );
exit( EXIT_FAILURE );
}
//continue after the converted number
p = q;
}
//remember how many numbers were converted
num_converted = i;
//print how many numbers were converted
printf( "Converted %d numbers:\n", i );
//print all the converted numbers
for ( i = 0; i < num_converted; i++ )
printf( "%ld\n", numbers[i] );
return 0;
}
If you run this code with the input 761 87 2387, followed by a newline character, then the output will be the following:
Converted 3 numbers:
761
87
2387

How to allocate a dynamic memory zone for a character string in C

Why doesn't this code work? What I have been trying to do is make a dynamic allocation for an unknown user input length of an array using int main(int ac, char ** ac) and malloc().
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av)
{
char *str;
int i;
str = malloc(sizeof(char) * (ac + 1));
i = 0;
if(str[i] != '\0')
{
i = i + 1;
printf("%s\n\t", str);
}
return(0);
}
Name the parameters of main() in the standardized way: int argc, char *argv[].
(note that argv[0] is the name of the executable, which may or may not be of interest to you)
First you need to allocate argc number of pointers to character. Optionally with a NULL sentinel value at the end if that makes sense for your program - don't confuse this with null termination though.
So you should rather have something like char** str_table = malloc(sizeof(*str_table) * argc);
For each item in str_table, allocate additional memory for strlen(argv[i]) + 1 characters, the actual data. In this case the +1 is for null termination and it is mandatory.
strcpy from argv[i] to your own array.
ac is not the length of any argument, but rather the argument count.
When the user specifies one argument this will always be 2.
If the program should only output the first argument you can just do:
#include <stdio.h>
int main(int argc, char **argv) {
if(argc == 2)
printf("%s\n", argv[1]);
return 0;
}
If you want to load the argument into a string you have to get it's length.
This can for example be done with the strlen() function:
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for malloc and free */
#include <string.h> /* for strlen and strcpy */
int main(int argc, char **argv) {
if(argc == 2) {
char *input_string;
int input_string_length;
input_string_length = strlen(argv[1]);
/* strlen() does not include the '\0' in the length */
input_string = malloc((input_string_length + 1) * sizeof(char));
strcpy(input_string, argv[1]);
printf("%s\n", input_string);
free(input_string);
}
return 0;
}
ac doesn't represent user input length (as you have been trying to allocate memory for ac+1) + str points to a raw memory location without any valid data, even then if you want to go with ac then:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //added for memset
int main(int ac, char **av)
{
char *str;
int i; //USELESS
str = malloc(sizeof(char) * (ac + 1)); //str points to a memory (if allocated) which contains garbage
i = 0; //NO USE
if(str) //checks if memory has been allocated - NO INCREMENT NEEDED OR VALID
{
printf("Memory has been successfully allocated");
memset(str,'\0',ac+1); //added for NULL termination
}
return(0);
}
In case you are trying to allocate memory on the stack, you may also look for VLA.
This statement
str = malloc(sizeof(char) * (ac + 1));
does not make sense.
Moreover the allocated array was not initialized. So this statement
if(str[i] != '\0')
results in undefined behavior.
It seems what you are trying to do is to output command line parameters by copying them in dynamically allocated arrays.
If so then the program can look the following way
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main( int argc, char * argv[] )
{
if ( argc > 1 )
{
char **s = malloc( ( argc - 1 ) * sizeof( char *) );
for ( int i = 0; i < argc - 1; i++ )
{
s[i] = malloc( strlen( argv[i+1] ) + 1 );
strcpy( s[i], argv[i+1] );
}
for ( int i = 0; i < argc - 1; i++ )
{
puts( s[i] );
}
for ( int i = 0; i < argc - 1; i++ ) free( s[i] );
free( s );
}
return 0;
}
If to run the program like for example
program Hello World
then the output will be
Hello
World
You can add yourself checks to the program that the memory allocations were successful.
There are some logic error in your code.
int ac is the number of arguments.
char **av contain the arguments.
For example : ./program arg1 arg2
av[0] is gonna be "./program"
av[1] is gonna be "arg1"
av[2] is gonna be "arg2"
av[2][0] is gonna be "a"
Now if you just want the size of the first argument you can use strlen() :
int size = strlen(av[1]);
What you need instead of your if statement is a while loop to go throught all the elements of av.
For example :
int i = 0;
while (i <= ac) {
printf("%s", av[i]);
...Your code...
i++;
}

Strlwr function - getting an error in xcode 9.2

I'm trying to convert a string from upper case to lower case to check if it is a palindrome, however I keep getting the error:
"function declaration is not a prototype"
I already added #include <string.h> in the header, but it still doesn't work. How do I get around this issue?
This is the code:
int main (void)
{
char *user_string, *user_string_rev;
/* the malloc function is used to make sure that enough memory is allocated for the string and that it does not overwrite memory boxes of other variables. */
user_string= (char*)malloc(BUFF_SIZE*sizeof(char));
user_string_rev= (char*)malloc(BUFF_SIZE*sizeof(char));
printf("Please enter a string:");
fgets(user_string,BUFF_SIZE, stdin); /* fgets function take the string the user inputs and stores it into user_string. */
user_string_rev=strcpy(user_string_rev, user_string); /*the strcpy takes the string the user inputs and copies it to user_string_rev. */
strlwr(user_string_rev);
palindrome_check(user_string,user_string_rev); /*this is the palindrome function used to check if the two strings are palindromes, it intakes two arguments, the two strings and does not return anything. */
return 0;
}
Replace :
strlwr(user_string_rev);
which is not a standard function with:
int i = 0;
while (user_string_rev[i])
{
if (isalpha(user_string_rev[i]))
user_string_rev[i] |= 32;
++i;
}
Don't forget to add the ctype header at the top of your .c file to use isalpha:
#include <ctype.h>
the following proposed code:
incorporates the comments to the question
cleanly compiles
properly checks for errors
will treat a string that is nothing but a newline as NOT a palindrome
And now the proposed code:
#include <stdio.h> // getline(), printf()
#include <stdlib.h> // free()
#include <ctype.h> // tolower()
#include <string.h> // strlen(), strchr()
// prototypes
void palindrome( char *, size_t length );
int main( void )
{
char *inputStr = NULL;
size_t lengthStr = 0;
printf("Please enter a string:");
if( -1 != getline( &inputStr, &lengthStr, stdin ) )
{
size_t length = strlen( inputStr );
for( size_t i = 0; i < length; i++ )
{
inputStr[i] = (char)tolower( inputStr[i] );
}
char *newline = strchr( inputStr, '\n' );
if( newline )
{
*newline = '\0';
length--;
}
palindrome( inputStr, length );
}
free( inputStr );
return 0;
}
void palindrome( char stringToCheck[], size_t length )
{
size_t index = length - 1; // don't check NUL terminator byte
size_t i;
for( i = 0; i < index; i++ )
{
if( stringToCheck[i] != stringToCheck[ index ] )
{
break;
}
index--;
}
if( i < index )
{
printf( "%s is not a palindrome\n", stringToCheck );
}
else
{
printf( "%s is a palindrome\n", stringToCheck );
}
}

Why are these words not appending in C?

I'm trying to write a function in which two words are appended into a third string, and this function must use malloc(). I'm first writing it in the main before I put it in a function. I have:
int main(void){
char *word = "Johnny";
char *word2 = " Boy";
char *buff = malloc(100 * sizeof(char));
printf("%d\n", sizeof(buff));
int ct;
for(ct = 0; ct < strlen(word); ct++){
buff = word;
}
printf("%s\n", buff);
printf("the counter is now %d\n", ct);
buff += ct;
for(ct; ct < 13; ct++){
buff = word2;
}
printf("%s\n", buff);
}
I want buff to say "Johnny Boy" but at the end of it, "Johnny" is overwritten, and it just says " Boy"
Listen, while we want to help, SO is not really meant to be a classroom environment. Plainly, you're struggling with a fundamental lack of understanding about pointers / string manipulation in C, which is very basic material. Get a BETTER book on C and compare this code to your work, and study on it until you understand the differences and exactly what's being done at each step.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char word[] = "Johnny";
char word2[] = " Boy";
char *temp;
char *buff = malloc(32 * sizeof(char));
if (buff == NULL) {
puts("allocation error");
return 1;
}
for (int ct = 0; ct <= strlen(word); ct++) {
buff[ct] = word[ct];
}
printf("%s\n", buff);
temp = buff + strlen(word);
for (int ct = 0; ct <= strlen(word2); ct++) {
temp[ct] = word2[ct];
}
printf("%s\n", buff);
free(buff);
return 0;
}
Okay. The first problem here is you must understand that strings are arrays. You cannot in c say that an array is another array. To be honest there are a lot of problems with this code. The guy above me's code is probably gonna be pretty complicated for you to understand so I will try to give you some more understandable code. One more thing, I won't be using pointers because I haven't mastered them yet.
#define BUF 255
int main( void)
{
char word1[BUF], word2[BUF], word_full[BUF];
int ct, length;
printf( "Input your first word\n" );
scanf( " %s", &word1);
printf( "Input your second word." );
scanf( " %s", &word2);
length = strlen( word1 );
for ( ct = 0; ct < length; ct++ )
{
word_full[ct] = word1[ct];
word_full[ ct + length ] = word2[ct];
}
word_full[BUF] = 0;
printf( word_full );
return 0;
}
return 0;
}

Resources