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;
}
Related
I'm trying to create word generator in C and found Segmentation Fault message.
gdb output :
_GI___strtok_r (
s=0x562d88201188 "some text without comma",
delim=0x562d8820117f " ", save_ptr=0x7f570a47aa68 <olds>) at strtok_r.c:72
code with strtox function :
char **words = malloc(sizeof(char *) * NUM_WORDS);
int num_words = 0;
char *save_ptr;
char *word = strtok(text, " ");
while (word != NULL) {
// Strip leading and trailing whitespace
while (isspace(*word)) {
word++;
}
int len = strlen(word);
while (len > 0 && isspace(word[len - 1])) {
len--;
}
// Allocate memory for the word and copy it using strdup()
words[num_words] = strdup(word);
// Move to the next word
num_words++;
word = strtok(NULL, " ");
}
how to use function with an indeterminate number of words in text?
Can't believe someone finally asked for this!
You may want to add verification that realloc() hasn't returned a NULL.
In brief, the string is chopped on the delimiters provided to strtok() while realloc() is used to grow an array of pointers to each of those segments.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char buf[] = "Once upon a time there lived a beautiful princess.", *p = buf;
char **t = NULL; size_t sz = sizeof *t;
int n = 0;
while(!!(t=realloc(t,(n+1)*sz))&&!!(t[n]=strtok(p," .\n"))) p=NULL, n++;
for( int i = 0; i < n; i++ )
puts( t[i] );
free( t );
return 0;
}
Once
upon
a
time
there
lived
a
beautiful
princess
EDIT
Then there is the extension that can handle multiple input lines:
int main() {
char *buf[] = { "Once upon a time\n", "there lived\n", " a beautiful princess.\n" };
char **t = NULL; size_t sz = sizeof *t;
int n = 0;
for( int ln = 0; ln < sizeof buf/sizeof buf[0]; ln++ ) {
char *p = buf[ln];
while(!!(t=realloc(t,(n+1)*sz))&&!!(t[n]=strtok(p," .\n"))) p=NULL, n++;
}
for( int i = 0; i < n; i++ )
puts( t[i] );
free( t );
return 0;
}
/* Output same as shown above */
Put the strtok() as the parameter to strdup() and you've got yourself something that will preserve words while using a single line input buffer.
I'm trying to tokenize a string without using a strtok().
When I run characters of string, it will print in each line.
For instance, when I run:
printfTokens("Hello from other side!");
The output should be:
Hello
from
other
side!
As I'm just learning C, I'm stuck for hours on how to implement this program. So far, I only know the basics and playing around with not (still haven't learned any calloc, malloc, etc).
So far I have this code, but the output does not print anything.
#include <stdio.h>
#include <string.h>
#define MAX_WORD 100
void printfTokens(char *inputString) {
int i;
/*int inputStringLength;
for(i = 0; inputString[i] != '/0'; i++) {
inputStringLength++;
}*/
while(inputString[i] != '\0') {
char testing[MAX_WORD];
while(inputString[i] != ' ') {
testing[inputString[i]]++;
i++;
}
printf("%s", testing);
i++;
}
}
int main() {
printfTokens("TESTING ONE! TWO! THREE!");
return 0;
}
You do not initialize the variable i.
while(inputString[i] != '\0') can be written while(inputString[i]).
testing[inputString[i]]++ makes sense to count the number of occurrences of a given character from inputString, but it does not make sense to print it. You may want to do something like:
while(1)
{
char testing[MAX_WORD], *t=testing;
while(inputString[i]&&(inputString[i]!=' '))
*t++=inputString[i++];
if (t>testing) printf("%s", testing);
if (!inputString[i]) break;
i++;
}
It would be better to name MAX_WORD_LENGTH instead of MAX_WORD.
These are a few problems in your code.
Sample tokenization function.
size_t tokenize(const char *inputString, const char *delim, char **argv, size_t maxtokens)
{
size_t ntokens = 0;
char *tokenized = strdup(inputString);
if(tokenized)
{
argv[0] = tokenized;
while(*tokenized)
{
if(strchr(delim, *tokenized))
{
*tokenized = 0;
ntokens++;
if(ntokens == maxtokens - 1)
{
break;
}
argv[ntokens] = tokenized + 1;
}
tokenized++;
}
}
return ntokens + 1;
}
int main()
{
char *tokens[10];
size_t ntokens = tokenize("TESTING ONE! TWO! THREE!", " ", tokens , 10);
for(size_t i = 0; i < ntokens; i++)
{
printf("Token[%zu] = `%s`\n", i, tokens[i]);
}
free(tokens[0]);
return 0;
}
https://godbolt.org/z/znv8PszG6
I am getting used to writing eBPF code as of now and want to avoid using pointers in my BPF text due to how difficult it is to get a correct output out of it. Using strtok() seems to be out of the question due to all of the example codes requiring pointers. I also want to expand it to CSV files in the future since this is a means of practice for me. I was able to find another user's code here but it gives me an error with the BCC terminal due to the one pointer.
char str[256];
bpf_probe_read_user(&str, sizeof(str), (void *)PT_REGS_RC(ctx));
char token[] = strtok(str, ",");
char input[] ="first second third forth";
char delimiter[] = " ";
char firstWord, *secondWord, *remainder, *context;
int inputLength = strlen(input);
char *inputCopy = (char*) calloc(inputLength + 1, sizeof(char));
strncpy(inputCopy, input, inputLength);
str = strtok_r (inputCopy, delimiter, &context);
secondWord = strtok_r (NULL, delimiter, &context);
remainder = context;
getchar();
free(inputCopy);
Pointers are powerful, and you wont be able to avoid them for very long. The time you invest in learning them is definitively worth it.
Here is an example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
Extracts the word with the index "n" in the string "str".
Words are delimited by a blank space or the end of the string.
}*/
char *getWord(char *str, int n)
{
int words = 0;
int length = 0;
int beginIndex = 0;
int endIndex = 0;
char currentchar;
while ((currentchar = str[endIndex++]) != '\0')
{
if (currentchar == ' ')
{
if (n == words)
break;
if (length > 0)
words++;
length = 0;
beginIndex = endIndex;
continue;
}
length++;
}
if (n == words)
{
char *result = malloc(sizeof(char) * length + 1);
if (result == NULL)
{
printf("Error while allocating memory!\n");
exit(1);
}
memcpy(result, str + beginIndex, length);
result[length] = '\0';
return result;
}else
return NULL;
}
You can easily use the function:
int main(int argc, char *argv[])
{
char string[] = "Pointers are cool!";
char *word = getWord(string, 2);
printf("The third word is: '%s'\n", word);
free(word); //Don't forget to de-allocate the memory!
return 0;
}
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
This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
I tried to develop a function which take a string reverse letters and return pointer to string.
char *reverseStr(char s[])
{
printf("Initial string is: %s\n", s);
int cCounter = 0;
char *result = malloc(20);
while(*s != '\0')
{
cCounter++;
s++;
}
printf("String contains %d symbols\n", cCounter);
int begin = cCounter;
for(; cCounter >= 0; cCounter--)
{
result[begin - cCounter] = *s;
s--;
}
result[13] = '\0';
return result;
}
in main function I invoke the function and tried to print the result in this way:
int main()
{
char testStr[] = "Hello world!";
char *pTestStr;
puts("----------------------------------");
puts("Input a string:");
pTestStr = reverseStr(testStr);
printf("%s\n", pTestStr);
free(pTestStr);
return 0;
}
but the result is unexpected, there is no reverse string.
What is my fault?
There are multiple mistakes in the shared code, primarily -
s++; move the pointer till '\0'. It should be brought back 1 unit to
point to actual string by putting s--. Other wise the copied one will start with '\0' that will make it empty string.
Magic numbers 20 and 13. where in malloc() 1 + length of s should be
sufficient instead or 20. For 13 just move a unit ahead and put '\0'
However, using string.h library functions() this can be super easy. But I think you are doing it for learning purpose.
Therefore, Corrected code without using string.h lib function() should look like this:
char *reverseStr(char s[])
{
printf("Initial string is: %s\n", s);
int cCounter = 0;
while(*s != '\0')
{
cCounter++;
s++;
}
s--; //move pointer back to point actual string's last charecter
printf("String contains %d symbols\n", cCounter);
char *result = (char *) malloc(sizeof(char) * ( cCounter + 1 ));
if( result == NULL ) /*Check for failure. */
{
puts( "Can't allocate memory!" );
exit( 0 );
}
char *tempResult = result;
for (int begin = 0; begin < cCounter; begin++)
{
*tempResult = *s;
s--; tempResult++;
}
*tempResult = '\0';
//result[cCounter+1] = '\0';
return result;
}
Calling from main
int main()
{
char testStr[] = "Hello world!";
char *pTestStr;
puts("----------------------------------");
puts("Input a string:");
pTestStr = reverseStr(testStr);
printf("%s\n", pTestStr);
free(pTestStr);
}
Output
----------------------------------
Input a string:
Initial string is: Hello world!
String contains 12 symbols
!dlrow olleH
As per WhozCraig suggestion just by using pointer arithmetic only -
char *reverseStr(const char s[])
{
const char *end = s;
while (*end)
++end;
char *result = malloc((end - s) + 1), *beg = result;
if (result == NULL)
{
perror("Failed to allocate string buffer");
exit(EXIT_FAILURE);
}
while (end != s)
*beg++ = *--end;
*beg = 0;
return result;
}
Your code can be simplified using a string library function found in string.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *reverseStr(char s[])
{
printf("Initial string is: %s\n", s);
int cCounter = strlen(s);
char *result = malloc(cCounter + 1);
printf("String contains %d symbols\n", cCounter);
int begin = cCounter;
for(; cCounter > 0; cCounter--)
{
result[begin - cCounter] = s[cCounter - 1];
}
result[begin] = '\0';
return result;
}
int main()
{
char testStr[] = "Hello world!";
char *pTestStr;
puts("----------------------------------");
puts("Input a string:");
pTestStr = reverseStr(testStr);
printf("%s\n", pTestStr);
free(pTestStr);
return 0;
}
Output:
----------------------------------
Input a string:
Initial string is: Hello world!
String contains 12 symbols
!dlrow olleH