As a part in my process to learn C I am developing a couple of functions for string manipulations. One of these has the function of replacing substrings within a string, and is raising some questions. I am working in C99; compiling on Mac OS Sierra and FreeBSD.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *repstr(char input[], char rep[], char new[]) {
char *output = malloc(strlen(input)*5); // <- Question 2
int replen = strlen(rep);
int newlen = strlen(new);
int a, b, c = 0;
// printf("input: %ld\t%s\n", strlen(input), input); // <- Question 1
while(input[a]) {
if(input[(a+b)] == rep[b]) {
if(b == replen - 1) {
strcat(output, new);
a += replen;
c += newlen;
b=0;
}
else b++;
} else {
output[c] = input[a];
a++;
c++;
}
}
return output;
}
int main() {
char buffer[] = "This is the test string test string test test string!";
char rep[] = "test";
char new[] = "tested";
int len = strlen(buffer);
char output[len+5];
printf("input: %d\t%s\n", len, buffer); // <- Question 1
strcpy(output, repstr(buffer, rep, new));
printf("output: %ld\t%s\n", strlen(output), output);
return 0;
}
Question 1: When this line is executed in main() it causes a segfault. However, when executed within the function everything seems to work fine. Why?
Question 2: I have realized that I need a pretty large piece of memory allocated for the output to look as expected. strlen(input)*5 is an arbitrary number which seems to work, but why do I get seemingly 'random' errors when lowering the number?
NB! As this is a part of my process to learn coding in C I am not primarily interested in (more efficient) pre-fab solutions for solving the problem (already have them), but to explain the two questions listed - so that I can solve the problem myself.
Also; this is my first post in the SO forums. Hello.
Question 1: When this line is executed in main() it causes a segfault.
However, when executed within the function everything seems to work
fine. Why?
No, printf("input: %d\t%s\n", len, buffer); // <- Question 1 is not the cause of your segfault.
printf("output: %ld\t%s\n", strlen(output), output);
This part is, strlen doesn't return int but it returns size_t. As noted in the comments, use %zu to print it out.
Also, while(input[a]) will stop at the NULL terminator which means that your output will never hold a terminator and thus printf will keep on reading, you should add it at the end:
output[c] = '\0';
Also, as noted by #LPs in the comments, you should zero initialize the variables you work with :
int a = 0, b = 0, c = 0;
Question 2: I have realized that I need a pretty large piece of memory
allocated for the output to look as expected. strlen(input)*5 is an
arbitrary number which seems to work, but why do I get seemingly
'random' errors when lowering the number?
Probably because you haven't allocated enough memory. Because the string length depends on runtime factors there's no way to know the exact memory needed you should allocate the maximum amount required:
char *output = malloc(strlen(input) * strlen(new) + 1);
Related
I'm trying to implement a C function char* strShiftLeft(char* str, int n) that takes in a string (str) and an int n, which represents how many chars to shift str to the left. For example, if we call it as strShiftLeft("Thomas", 2), the function should return a char pointer pointing to a string "omasTh" as we append the first 2 (n) chars to the end of string and shift every char 2 slots to the left.
However, for some reason, when I compile my program, it compiles fine but when I run it on my mac, my terminal keeps showing me:
zsh: bus error ./a.out
Here's my code:
#include <stdio.h>
#include <stdlib.h>
char* strShiftLeft(char* str, int n)
{
// If the passed in string is NULL, return NULL
if (str == NULL)
{
printf("NULL!\n");
return NULL;
}
// Get the length of the string
int len = 0;
char* counter_ptr = str;
while (*counter_ptr != '\0')
{
len++;
counter_ptr++;
}
printf("len: %d\n", len);
// If the integer is longer than the string, return back NULL
if (n > len)
{
printf("n too big!\n");
return NULL;
}
// Create a temp char array to store 1st n chars to append to the end of string later
char temp_arr[n];
for (int i = 0; i < n; i++)
{
*(temp_arr + i) = *(str + i);
}
printf("temp_arr = %s\n", temp_arr);
printf("str is still: %s\n", str);
// So far so good
char* temp = str + n;
printf("len - n = %d\n", len - n);
// Update first (len - n) characters of the string (e.g. n = 2, "Thomas" -> "omasas")
for (int i = 0; i < (len - n); i++)
{
printf("*temp = %c\n", *temp);
printf("*(temp - n) = %c\n", *(temp - n));
*(temp - n) = *(temp); // THIS LINE SEEMS TO BE THE ONE CAUSING ERRORS
temp++;
}
temp = str + (len - n);
for (int i = 0; i < n; i++)
{
*(temp + i) = *(temp_arr+i); // THIS LINE ALSO SEEMS TO BE CAUSING ERRORS
}
return str;
}
int main()
{
char* str = strShiftLeft("Thomas", 2);
printf("%s\n", str); // Should print out "omasTh"
return 0;
}
I used a lot of printf()s to try to find out what went wrong. I noticed two particular lines of code seem to be causing some errors, namely:
1)
*(temp - n) = *(temp);
*(temp + i) = *(temp_arr+i);
What I'm trying to do with these 2 lines of code is that I want to update the values of certain elements in the string with values from other elements in the string.
Although my code compiles, when I run it, it shows "zsh: bus error ./a.out". I tried using some online compiler. When I ran my code, I got seg fault.
I don't know what mistakes I've made.
Would be much appreciated if someone can help me identify the mistakes I've made.
Note that, I'm not allowed to use dynamic memory allocation, bracket operator for dereferencing pointers, or any functions from the C library such as strlen(), strcpy() etc. Thanks!
I've used printf() to pinpoint which lines are causing errors, but I don't understand why they're causing errors.
When you invoke strShiftLeft("Thomas", 2); you are passing strShiftLeft() the address of a string literal.
strShiftLeft() then proceeds to try and modify in-place the string that you passed to it, which means that it tries to modify a string literal.
Modifying a string literal in C is "undefined behavior", which means that anything may happen.
Anything includes:
Nothing. This will happen if you are running in some environment which happens to be storing C string literals in read-write memory. (And is treacherous, because it might give you the impression that your program works, while it doesn't.)
Bowls of petunias and sperm whales fall from the sky. (Mandatory HGGTG reference.)
More likely: Your program gets terminated due to a segmentation fault (segfault) because the string literal was stored in read-only memory and your program attempted to write to that memory.
However, this is not what is happening in your case, because you are not receiving a segfault, you are receiving a bus error. A bus error means that your program did not just attempt to write to read-only memory; it means that it attempted to address memory which cannot even be addressed.
What is causing your bus error is most probably the following:
printf("temp_arr = %s\n", temp_arr);
What happens is that you forgot to null-terminate your temp_arr, so the printf() function prints whatever temp_arr contains and then continues printing after the end of temp_arr. Since temp_arr is in the stack, printf() attempts to read from memory past the end of the stack, which is in all likelihood some invalid page.
This is one more reason to start using a debugger and stop using printf() statements.
I have a for loop which should run 4 times but is running 6 times.
Could you please explain the behaviour?
This is strange because stringarr1 is not changed.
Edit: I want to remove all '!' from my first string and want to save the letters in a second string.
#include <stdio.h>
#include <math.h>
#include <string.h>
int main(){
char stringarr1[] = "a!bc";
char stringarr2[] = "";
printf("%d\n", strlen(stringarr1)); // lenght --> 4
for (size_t i = 0; i < strlen(stringarr1); i++)
{
printf("i: %d\n", i);
if (stringarr1[i] != '!') {
stringarr2[strlen(stringarr2)] = stringarr1[i];
printf("info: != '!'\n");
}
}
}
You are overrunning the buffer for stringarr2 (length 1), which is in this case corrupting the memory-adjacent stringarr1, causing the string length to change by overwriting its nul terminator.
Then because you are reevaluating the string length on each iteration, the loop will run for a non-deterministic number of iterations - in your case just 6, but it could be worse; the behaviour you have observed is just one of several possibilities - it is undefined.
Apart from correcting the buffer length for stringarr2, it is best practice to evaluate loop-invariants once (although in this case the string length is not invariant due to a bug). So the following:
const size_t length = strlen( stringarr1 ) ;
for( size_t i = 0; i < length; i++ )
{
...
will run for 4 iterations regardless of the buffer overrun bug because the length is not reevaluated following the corruption. Re-evaluating loop-invariants can lead to very slow code execution.
Your code can run any number of times. You write beyond the end of stringarr2 so you may be smashing the stack and overwriting local variables. What you meant to do is probably something like this:
#include <stdio.h>
#include <math.h>
#include <string.h>
int main(){
char stringarr1[] = "a!bc";
char stringarr2[10];
int len = strlen(stringarr1);
printf("%d\n", len); // lenght --> 4
for (size_t i = 0; i < len; i++)
{
printf("i: %d\n", i);
if (stringarr1[i] != '!') {
stringarr2[len] = stringarr1[i];
printf("info: != '!'\n");
}
}
}
Like others said, it is not really clear what you are trying to accomplish here. But in C, a declaration like char s[] = "string" only allocates enough memory to store whatever is on the right hand side of the assignment. If that is an empty string like in your case, only a single byte is allocated, to store the end of string 'null' character. You need to either explicitly specify, like I did, the number of bytes to allocate as the array size, or use dynamic memory allocation.
The problem is that you're writing past the end of stringarr2. This triggers undefined behaviour.
To fix this, you need to allocate sufficient memory for stringarr2.
First, we must allocate the string to be long enough.
char stringarr1[] = "a!bc";
//save this in a variable beforehand because strlen loops over the string every time it is called
size_t len = strlen(stringarr1);
char stringarr2[1024] = { 0 };
{ 0 } initializes all characters in the string to 0, which means the last one will always be a null terminator after we add characters. This tells C string functions where the string ends.
Now we can put stuff in there. It seems like you're trying to append, so keep a separate iterator for the 2nd string. This is more efficient than calling strlen every loop.
for(size_t i = 0, j = 0; i < len; i++){
printf("i: %d\n", i);
if (stringarr1[i] != '!') {
stringarr2[j++] = stringarr1[i];
printf("info: != '!'\n");
}
}
This question already has answers here:
Why does C's printf format string have both %c and %s?
(11 answers)
Closed 4 years ago.
In a nutshell, I have to be able to return the character in the middle of an input (char array) for part of our first C assignment. What I have so far, however, is code that returns "Segmentation fault (core dumped)". I read into this a little bit, and learned that essentially I may be trying to access/modify data that is "not available to me", so-to-speak. Here is my code:
#include <stdio.h>
#include <string.h>
char input[30];
int inputLen;
char midChar;
int main()
{
printf("Type in some text, and the press the Return/Enter key: ");
fgets(input,sizeof(input),stdin);
printf("\nYour input: %s",input);
inputLen = strlen(input)-1;
printf("Length of your input is %d characters.",inputLen);
if((inputLen % 2) == 0) {
midChar = input[(inputLen/2)+1]; // >>> PROBLEM HERE <<<
}
else {
midChar = input[((inputLen+1)/2)+1]; // >>> PROBLEM HERE <<<
}
printf("%s",midChar);
return 0;
}
The two lines with >>> PROBLEM HERE <<< are the lines which I believe I've narrowed down to be the source of the problem.
Please Note: I have taken an introductory class in Java, and last semester took a class half-devoted to MATLAB, so I do have a little bit of programming intuition -- However, I am a 100% beginner in C, so I would appreciate some clear elaboration behind any help you guys may offer. I am not familiar with most functions/syntax unique to C, so I'm sure there will be cringe-worthy lines of code above for those well-versed in this language. If this is the case, feel free to include any other tips in your answers. Thanks!
You're printing a char with %s, so the program is treating your input as a pointer (to a char array). It's not a valid such thing.
You meant %c for a single character.
Your compiler should tell you about this. Turn warnings on!
A late addition:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
// This will be the default value if a string of length 0 is entered
char midChar = 0;
int inputLen;
int bufferLen = 31;
char* input = (char*)malloc(sizeof(char) * bufferLen);
printf("Type in some text, and the press the Return/Enter key: ");
fgets(input, bufferLen, stdin);
printf("\nYour input: %s", input);
inputLen = strlen(input);
if (input[inputLen - 1] == '\n') {
inputLen--; // ignore new line character
}
printf("Length of your input is %d characters.\n", inputLen);
if (inputLen > 0) {
midChar = input[inputLen / 2]; // take right of middle for even number
}
printf("%c\n", midChar);
return 0;
}
In your previous post you used sizeof(input) which is not recommended for reasons described in this post. It is better practice to hold the length of the array in a separate variable, here bufferLen.
Also the use of global variables here input inputLen midChar is generally discouraged as they lead to unexpected behaviour during linking and make program flow harder to understand.
I initialised the memory for the buffer dynamically so the bufferLen could be changed in the program.
When computing the length of the input one must consider the newline character \n which is retained if a small enough string is entered but not if the entered string exceeds the bufferLen.
For strings with even lengths I arbitrarily took the character to the right. The inputLen zero case is also handled.
This whole answer is only an addition to the first one which already found the bug correctly, because I was late to the party.
Other than print char problem, I think there is also a problem at where you indicated.
ex. if input string is abc, inputLen will be 3, midchar index should be at 1 since array index in C start from 0. However ((inputLen+1)/2)+1 gives 3. This probably won't directly cause the segfault but will give wrong answer.
You can replace
if((inputLen % 2) == 0) {
midChar = input[(inputLen/2)+1]; // >>> PROBLEM HERE <<<
}
else {
midChar = input[((inputLen+1)/2)+1]; // >>> PROBLEM HERE <<<
}
with
midChar = input[inputLen/2];
since C will truncate when doing integer division.
a b c -> 3/2 = 1
[0] [1] [2]
a b c d -> 4/2 = 2
[0] [1] [2] [3]
Other than that, you also need to make sure the inputLen is not 0
Although "pretty lady" (#LightnessRasesInOrbit) up here is correct, let me explain what is happening when you do this:
printf("%s\n", charVar);
or this:
printf("%s\n", intVar);
or this:
printf("%s\n", floatVar);
Or when you print things using pritnf() with %s. You have to understand how does printf ("%s", string) work!! So when printf gets %s it looks for C string or in other words, character array terminated with '\0'. If it does not '\0' it will segfault. In depth, printf() works like this:
char name[4];
printf("Hello ", name);
now printf does following:
gets the size of 1st variable ("Hello")
gets the size of 2nd variable (name) How? Simple by this loop:
int varSize;
for (varSize = 0; varSize != '\0'; ++varSize);
moves "Hello" into buffer
Determine the size of second parameter. How, by doing this:
does following
if ("%d")
// read intVar and attach it to the buffer
if ("%f")
// read floatVar and attach it to the buffer
if ("%s")
for (int i = 0; stringVar[i] != '\0'; ++i)
// push each char into the buffer
So I hope you see what is happening if one of for() loops does not find '\0' character. If you do good if you don't well it continues reading through until it segfaults.
NOTE:
This is oversimplified pseudo code on how printf() works and is not actual implementation, this is only for OP to understand what is going on.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I honestly have no idea how the following even happens. Here is the code:
while(1)
{
char** line = read_command();
char* command = line[0];
char** parameters = malloc(100);
int i;
for(i = 0; i < pNum; i++) // pNum is a global var containing the number of words read from read_command()
{
parameters[i] = line[i];
printf("%i: %s", i, parameters[i]);
}
printf("%s\n", parameters[0]);
parameters[0] = "/usr/bin/";
strcat(parameters[0], command);
printf("%s\n", command);
printf("%s\n", parameters[0]);
if(fork() != 0)
waitpid(1, &status, 0);
else
execve(parameters[0], parameters, NULL);
}
read_command() returns a char** that is basically an "array" to the string that was entered, and each char* contains a word. Like if I enter "hello people of earth" the result would be ["hello", "people", "of", "earth"]. This fucntion always works.
upon the first iteration everything works just as expected. example, when I type "date" the output is as follows:
0: date
date
date
/usr/bin/date
and then the date is displayed
but upon the second iteration if i use "date" as the input again the output is as follows:
0:date
edate
/usr/bin/datedate
and the date command is not issued
the second printf statement always prints "e" after the first iteration even if I print a constant string like "hello". and then the parameters[0] somehow has 2 "date" in it even though the command pointer has only 1 "date".
And after the third iteration the program does not wait for user input, it just loops non stop and displays "PM: warning, process table is full!"
What could possibly cause this?
I am working in MINIX 3.1.0 with the cc compiler for C
EDIT:
the read_command():
char* line = malloc(), * linep = line;
size_t lenmax = 100, len = lenmax;
int c;
int currPos = 0;
int currParam = 0;
int i;
char** parameters = malloc(100);
if(line == NULL)
return NULL;
while(1)
{
c = fgetc(stdin);
if(c == EOF) || c == '\n')
break;
if(--len == 0)
{
char* linen = realloc(linep, lenmax *= 2);
len = lenmax;
if(linen == NULL)
{
free(linep);
return NULL;
}
line = linen + (line - linep);
linep = linen;
}
if((*line++ = c) == '\n')
break;
}
*line = '\0'; // everything up to this point i got from this link: http://stackoverflow.com/a/314422/509914
parameters[currentParam] = malloc(100);
for(i = 0; i < strlen(linep); i++);
{
if(isspace(linep[i]) || line[i] == EOF)
{
parameters[currParam][currPos] = '\0;
currPos = 0;
parameters[++currParam] = malloc(100);
}
else
parameters[currParam][currPos++] = line[i];
}
parameters[currParam][currPos] = '\0';
pNum = currParam + 1;
return parameters;
It sure is interesting that those people who learn by reading reputable resources, such as the tried and tested for decades K&R tend to have these issues far less frequently than those who don't...
char** parameters = malloc(100); is attempting to allocate 100 bytes. realloc behaves similarly, so I won't mention this again. Perhaps you meant to allocate 100 lots of char *? It'd make even more sense to allocate pNum lots of char *: char **parameters = malloc(pNum * sizeof *parameters);... char* linen = realloc(linep, (lenmax *= 2) * sizeof *linep);...
strcat doesn't allocate memory; the only functions that allocate memory are malloc, calloc and realloc.
When you call strcat(foo, bar); you're asking strcat to append the string pointed to by bar onto the end of the string pointed to by foo. In your code, you're attempting to modify a string literal. Undefined behaviour, and typically a segfault.
Even your modified attempt is wrong. In parameters[0] = "/usr/bin/";, you're not copying a string into parameters[0]; you're assigning parameters[0] to point to the string (which is typically in immutable memory, as I mentioned earlier). You really need to narrow down the source of your undefined behaviour by creating an MCVE...
In the first line of your read_command() function, char* line = malloc(), * linep = line;, you have called malloc without providing an argument. That's a constraint violation. Your compiler should be issuing you with an error. Perhaps you've forgotten to #include <stdlib.h>, and so malloc is missing its prototype? Please provide an MCVE so we don't have to make guesses like this.
There's another constraint violation at if(c == EOF) || c == '\n')... Even if we were to fill in the blanks to produce an MCVE for you (which we shouldn't have to do, because it's your work and you're asking us for help), this code would not compile. Perhaps that's what's causing your crashes? Always check the messages that your compiler gives you. Don't ignore warnings... and definitely don't ignore error messages.
I compared the code that you claimed came from this answer, and it is quite different. The code at that answer compiles, for one. Nonetheless, is that your way to establish trust with the people who are trying to help you... by lying?
You don't need so much dynamic allocation, and normally I would go out of my way and explain how you can do this the best way possible, but the lies have put me off. I have one more point to make: Make sure parameters is terminated by a null pointer (similarly to how strings are terminated by a null character), as it is required to be by the manual.
Hello and sorry for my bad english.
I am starting with C language, but I didnt get pointers well...
I searched for similar topics, but I didnt get it from them, so I created own topic.
I have got main function, where I call function newSpeak.
There is my code of newSpeak, but there isnt everything...
char * newSpeak ( const char * text, const char * (*replace)[2] )
{
int i;
char * alpha;
for(i=0;i<4;i++)
{
alpha=strstr(text, replace[0][4]);
if(alpha[0])
strncpy (alpha,replace[1][0],10);
}
return 0;
}
Thanks for answering
EDIT: I have found source of the problem.
It works, when I dont use for cycle and run it once. But it doesnt work even when the condition in for cycle is i<1, which should make it run only once...This is strange for me...
alpha=strstr(text, replace[0][4]);
if(alpha[0])
// looks crashy
man strstr:
These functions return a pointer to the beginning of the substring,
or NULL if the substring is not found.
EDIT:
It is difficult to tell what you are trying to do, but below find an arbitrary adaptation of your code. If it were my program, I would write it very differently. I mention that because I do not want someone to read this and think it is the way it should be done.
#include <stdio.h>
#include <string.h>
void newSpeak (char *text, const char *replace[4][2])
{
int i, j;
char *alpha;
for (i = 0; i < 4; i++) {
if (alpha = strstr(text, replace[i][0])) {
for (j = 0; alpha[j] && replace[i][1][j]; j++)
alpha[j] = replace[i][1][j];
}
}
}
int main ()
{
char buf[100] = "abc";
const char *replace[4][2] = {
{ "a", "e" },
{ "b", "f" },
{ "c", "g" },
{ "d", "h" },
};
newSpeak(buf, replace);
puts(buf);
}
The line
strncpy (alpha,replace[1][0],10);
should have generated a compiler warning (and NEVER ignore compiler warnings). The function prototype is
char *strncpy( char *dest, char *source, int n);
But you are passing it replace[1][0] which is a character. It might work if you passed
strncpy( alpha, &replace[1][0], 10);
Even then I still worry. It could be that since alpha is pointing to a block of memory in the block pointed to by text which is a const char*, that you are not allowed to modify that memory.
EDIT I think my first point is wrong - I misread your prototype. But I'm pretty sure the second point is valid (and probably the reason for the segfault).
second edit
It is possible that text does not have sufficient memory allocated to have 10 characters copied into it from replace. Realize that the thing you are matching against (replace[0][4]) and the thing you are copying (replace[1][0]]) are not the same thing; also, you are looping over i but not using that value ... makes me wonder if there is a typo (I am not clairvoyant and cannot figure out what you wanted to change from loop to loop).
You need to check the size of the thing you are copying into:
strncpy(alpha, replace[1][0], (strlen(alpha)<10)?strlen(alpha):10);
would ensure you are copying no more than 10 characters, and no more than there's space in alpha.
This is "on top of" everything else already pointed out (of which using if (alpha!=NULL) instead of if(alpha[0]) is a big one.)
EDIT 3 - I think I figured out the majority of the problems with your code now... see http://codepad.org/YK5VyGAn for a small "working" sample.
Issues with your code included:
You declare text as const char*, then proceed to modify it
You declare replace as const char* (*replace)[2], then address element replace[0][4] (4 > 2...)
You assign the return value of strstr to alpha; this could be NULL (no match), yet you test for alpha[0] (which will fail if alpha == NULL).
When you copied the replacement string, you copied "up to 10 characters" - regardless of whether (a) the target string could accommodate this, and (b) the source string had this many characters. The result might be that you copy the full source string (including the terminating '\0') so that you will not find another match afterwards (you have "deleted" the rest of the string). And then you will run into the "strstr returns NULL" error...
Not sure (without seeing your input string or "replace" strings) which of these actually caused your code to fail - I have written a small program that addresses all of these mistakes. You can find it at http://codepad.org/4jSOnmPy - reproduced here:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MIN(a,b) (a>b)?(b):(a)
char * newSpeak (const char *text, const char *(*replace)[5] ){
int ii=0, n;
char *alpha, *beta;
printf("length of input string is %d\n", strlen(text));
beta = malloc(strlen(text)+1);
printf("allocated %d bytes\n", strlen(text)+1);
fflush(stdout);
strcpy(beta, text);
printf("copy OK: beta now %s\n", beta);
fflush(stdout);
for(ii = 0; ii < 4; ii++) {
// alpha=strstr(beta, replace[0][0]);
alpha=strstr(beta, "a");
printf("alpha is '%s'\n", alpha);
fflush(stdout);
if(alpha!=NULL) {
char *rs;
rs = replace[1][ii];
printf("ii = %d; alpha now: '%s'\n", ii, alpha);
fflush(stdout);
n = MIN(strlen(alpha), strlen(rs));
printf("n is now %d\n", n);
fflush(stdout);
printf("going to copy at most %d characters from '%s' into '%s'\n", n, rs, alpha);
fflush(stdout);
strncpy (alpha,rs,n);
printf("beta is now '%s'\n", beta);
fflush(stdin);
}
else printf("no match found\n");
}
return beta;
}
int main(void) {
char* r[2][5]={{"a","b","c","d", "e"}, {"o","e","i","u","s"}};
char* myText = "this is a vary sally strang";
printf("NewSpeak: %s\n", "hello world");
printf("converted: %s\n", newSpeak(myText, r));
return 0;
}
Output:
NewSpeak: hello world
length of input string is 27
allocated 28 bytes
copy OK: beta now this is a vary sally strang
alpha is 'a vary sally strang'
ii = 0; alpha now: 'a vary sally strang'
n is now 1
going to copy at most 1 characters from 'o' into 'a vary sally strang'
beta is now 'this is o vary sally strang'
alpha is 'ary sally strang'
ii = 1; alpha now: 'ary sally strang'
n is now 1
going to copy at most 1 characters from 'e' into 'ary sally strang'
beta is now 'this is o very sally strang'
alpha is 'ally strang'
ii = 2; alpha now: 'ally strang'
n is now 1
going to copy at most 1 characters from 'i' into 'ally strang'
beta is now 'this is o very silly strang'
alpha is 'ang'
ii = 3; alpha now: 'ang'
n is now 1
going to copy at most 1 characters from 'u' into 'ang'
beta is now 'this is o very silly strung'
converted: this is o very silly strung
Note - I added lots of "useless" output, including fflush(stdout); statements. This is a good way to ensure that debug printout shows you exactly how far into a program you got, and what was going on before it crashed - without the fflush it's possible you are missing many lines of output (because they never "made it to the screen").
It's obvious from the above that if your replacement strings are a different length than the string they replace, you will get some strange overwriting (I left both search and replace string length at 1 but there is no reason why that should be so).
I hope this helps!