C upper case to lower case - c

I am having issue with lower casing my words that are being used as inputs. So my program takes in words and sorts them alphabetically and removes duplicates. But I'd like to change words upper case and lower them to equal to lower case words.
example: Apple changes to apple
my input:
./a.out Orange apple banana Apple banana
my output:
Apple
Orange
apple
banana
Here is what I am trying to achieve
output:
apple
banana
orange
Here is my code
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
int i, j, k, size;
size = argc -1;
char *key;
char* a[argc-1];
for (i = 2; i < argc; i++) {
key = argv[i];
j = i-1;
while (j >= 1 && strcmp(argv[j], key) > 0) {
argv[j+1] = argv[j];
j--;
}
argv[j+1] = key;
}
if (argc > 1){
for (i = 1; i < argc;){
puts(argv[i]);
while (argv[++i] != NULL && strcmp(argv[i - 1], argv[i] ) == 0)
continue;
}
}
return 0;
}

You have a list of words and you want to output them sorted, and only the unique ones. And you want to do it in a case insensitive fashion.
Get all the strings to the same case.
Sort the list of strings.
Don't output repeats.
C has no built in function to lower case a string, but it does have ones to lower case characters: tolower. So we write a function to lower case a whole string by iterating through it and lower casing each character.
void str_lower(char *str) {
for( ; str[0] != NULL; str++ ) {
str[0] = (char)to_lower(str[0]);
}
}
Then we need to sort. That's handled by the built in qsort function. To use it, you need to write a function that compares two strings and returns just like strcmp. In fact, your comparison function will just be a wrapper around strcmp to make qsort happy.
int compare_strings( const void *_a, const void *_b ) {
/* The arguments come in as void pointers to the strings
and must be cast. Best to do it early. */
const char **a = (const char **)_a;
const char **b = (const char **)_b;
/* Then because they're pointers to strings, they must
be dereferenced before being used as strings. */
return strcmp(*a, *b);
}
In order to handle any data type, the comparison function takes void pointers. They need to be cast back into char pointers. And it's not passed the string (char *) it's passed a pointer to the string (char **), again so it can handle any data type. So a and b need to be dereferenced. That's why strcmp(*a, *b).
Calling qsort means telling it the array you want to sort, the number of items, how big each element is, and the comparison function.
qsort( strings, (size_t)num_strings, sizeof(char*), compare_strings );
Get used to this sort of thing, you'll be using it a lot. It's how you work with generic lists in C.
The final piece is to output only unique strings. Since you have them sorted, you can simply check if the previous string is the same as the current string. The previous string is strings[i-1] BUT be sure not to try to check strings[-1]. There's two ways to handle that. First is to only do the comparison if i < 1.
for( int i = 0; i < num_strings; i++ ) {
if( i < 1 || strcmp( strings[i], strings[i-1] ) != 0 ) {
puts(strings[i]);
}
}
Another way is to always output the first string and then start the loop from the second.
puts( strings[0] );
for( int i = 1; i < num_strings; i++ ) {
if( strcmp( strings[i], strings[i-1] ) != 0 ) {
puts(strings[i]);
}
}
This means some repeated code, but it simplifies the loop logic. This trade-off is worth it, complicated loops mean bugs. I botched the check on the first loop myself by writing if( i > 0 && strcmp ... )`.
You'll notice I'm not working with argv... except I am. strings and num_strings are just a bit of bookkeeping so I didn't always have to remember to start with argv[1] or use argv+1 if I wanted to pass around the array of strings.
char **strings = argv + 1;
int num_strings = argc-1;
This avoids a whole host of off-by-one errors and reduces complexity.
I think you can put the pieces together from there.

There are a set of standard functions for checking and changing the type of characters in ctype.h. The one you are interested in is tolower(). You can #include<ctype.h> and then add a snippet like the following to pre-process your argv before doing the sorting:
for(i = 1; i < argc; i++) {
argv[i][0] = tolower(argv[i][0]);
}
That will only operate on the first character of each word. If you need to normalize the entire word:
for(i = 1; i < argc; i++) {
for(j = 0; argv[i][j]; j++) {
argv[i][j] = tolower(argv[i][j]);
}
}

Silly me, I was able to figure it out after looking at my code realizing that i can do key[0] = tolower(key[0]); which i did before having a pointer point at it.
for (i = 2; i < argc; i++) {
key = argv[i];
key[0] = tolower(key[0]);
j = i-1;
while (j >= 1 && strcmp(argv[j], key) > 0) {
argv[j+1] = argv[j];
j--;
}
argv[j+1] = key;
}
Which lower cases the first letter. And if i wanted to lower case all the letters, i would've have used a for loop. Thank you everyone for your contribution. :)

Related

Split character array into multiple parts

In C, how would I go about splitting a char array into multiple parts, then back into an array. I am looking to split into 10 parts. But to make sure when it's split, it's split at a space and not by the character count.
I would like to be able to split it into another array so I can just call the index for each of them. But I am rather new to C/C++. In Java, I assume I could create an Array and then call array[0]-array[9] to get the split values after the operation is complete.
I would have:
char *s1 = "An example array that can be present right here. With a lot more words than this. But this is just an example after all. So does it really matter currently?"
And would need to be split into 10 parts (doesn't need to be equal in length) but just in 10 semi-equal parts.
So there are two parts to this:
a function that can find the closest space character to the next split point
a function that finds the next wrap point and saves the resulting string
For the first function, we need to pass in the string, its size, the last wrap point, and the next potential wrap point. It needs to return the next actual wrap point. So the function will have a definition like this:
int wrappoint(const char *string, int size, int previous, int current);
To find the next wrap point we need to search for a space character from the current wrap point both forward (until the end of the string) and backward (until the previous wrap point):
int before=-1, after=-1;
for(int i=current; i>previous; i--)
if(string[i] == ' ')
{ before = i; break; }
for(int i=current; i<=size; i++)
if(string[i] == ' ')
{ after = i; break; }
At this point before and after will contain the indices of the nearest space characters - or -1 if a space was not found i nthat direction. Then we just need to return a valid next wrap point based on what we found:
if(before==-1 && after==-1)
return size;
else if(before==-1)
return after;
else if(after==-1)
return before;
else if(current-before < after-current)
return before;
else
return after;
For the second function, we can just pass the string and the number of parts. The function will dynamically allocate an array big enough to hold all the parts. Each array index will be a pointer to a dynamically allocated string. Then the function can return the array and it will be the caller's responsibility to free all that memory. So the function will have a definition like this:
char **split(const char *string, int parts) {
The first thing we need to do is find the length of the string and make an array to hold all the parts. We use calloc so that any indices we don't use will be set to NULL:
char **array = calloc(parts, sizeof(char *));
int size = strlen(string);
Then we have to loop through the string, calling the wrappoint function to find the start and end of each part, allocating space for that part and then copying that part into the array:
int previous = 0, current = 0;
for(int i = 0; i < parts && current < size; i++) {
current = wrappoint(string, size, previous, previous+size/parts);
array[i] = malloc(current-previous+1);
strncpy(array[i], string+previous, current-previous);
array[i][current-previous] = '\0';
previous = current+1;
}
Then we can call split, which returns an array containing the parts - but some of them might be NULL if there are fewer spaces in the string than the number of parts we asked for. We can display the array of parts like this:
for(int i=0; i<10 && array[i]; i++)
printf("%d: %s\n", i, array[i]);
And then when we are done we have to free all the memory that split allocated:
for(int i=0; i<10 && array[i]; i++)
free(array[i]);
free(array);
Here is the full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int wrappoint(const char *string, int size, int previous, int current) {
int before=-1, after=-1;
for(int i=current; i>previous; i--)
if(string[i] == ' ')
{ before = i; break; }
for(int i=current; i<=size; i++)
if(string[i] == ' ')
{ after = i; break; }
if(before==-1 && after==-1)
return size;
else if(before==-1)
return after;
else if(after==-1)
return before;
else if(current-before < after-current)
return before;
else
return after;
}
char **split(const char *string, int parts) {
char **array = calloc(parts, sizeof(char *));
int size = strlen(string);
int previous = 0, current = 0;
for(int i = 0; i < parts && current < size; i++) {
current = wrappoint(string, size, previous, previous+size/parts);
array[i] = malloc(current-previous+1);
strncpy(array[i], string+previous, current-previous);
array[i][current-previous] = '\0';
previous = current+1;
}
return array;
}
int main() {
char *string = "An example array that can be present right here. With a lot more words than this. But this is just an example after all. So does it really matter currently?";
char **array = split(string,10);
for(int i=0; i<10 && array[i]; i++)
printf("%d: %s\n", i, array[i]);
for(int i=0; i<10 && array[i]; i++)
free(array[i]);
free(array);
return 0;
}
Try it at https://onlinegdb.com/uoDzM2toi
This example string:
An example array that can be present right here. With a lot more words than this. But this is just an example after all. So does it really matter currently?
Produces this output:
0: An example array
1: that can be present
2: right here. With
3: a lot more words
4: than this. But
5: this is just an
6: example after
7: all. So does it
8: really matter
9: currently?

Design a Character Searching Function, While Forced to Use strchr

Background Information
I was recently approached by a friend who was given a homework problem to develop a searching algorithm. Before anyone asks, I did think of a solution! However, my solution is not what the teacher is asking for...
Anyway, this is an introductory C programming course where the students have been asked to write a search function called ch_search that is supposed to search an array of characters to determine how many times a specific character occurs. The constraints are what I don't understand...
Constraints:
The arguments are: array to search, character to search for, and length of the array being searched.
The function must use a for-loop.
The algorithm must use the strchr function.
Okay, so the first two constraints I can understand... but the 3rd constraint is what really gets me... I was initially thinking that we could just use a for-loop to iterate through the string from the beginning to the end, simply counting each instance of the character. When the student originally described the problem to me, I came up with (although incorrect) the solution:
Proposed Solution
int ch_search(char array_to_search[], char char_to_search_for, int array_size)
{
int count = 0;
for (int i = 0; i < array_size; i++)
{
// count each character instance
if (array_to_search[i] == char_to_search_for)
{
// keep incrementing the count
count++;
}
}
return count;
}
Then I was told that I had to specifically use the character position function (and apparently it has to be strchr and not strrchr so we can't start at the end I guess?)... I just don't see how that wouldn't be overcomplicating this. I don't see how that would help at all, especially counting from the beginning... Even strrchr might make a little more sense to me. Thoughts?
It's true that having the length of the array and having to use a for loop,
the most natural thing to do would be to iterate over every characters of the
source array. But you can also loop over the result of strchr like this:
int ch_search(char haystack[], char needle, int size)
{
int count = 0;
char *found;
for(; (found = strchr(haystack, needle)) != NULL; haystack = found + 1)
count++;
return count;
}
In this case you don't need the size of the array but the assignment doesn't say
that you have to use it. Obviously this solution requires the source to be '\0'-terminated.
I think the teacher wanted you to use strchr to navigate to the next occurrence of the char_to_search_for within a string:
int ch_search(char array_to_search[], char char_to_search_for, int array_size) {
int count = 0;
for (char *ptr = array_to_search ; ptr != &array_to_search[array_size] ; ptr++) {
ptr = strchr(ptr, char_to_search_for);
if (!ptr) {
break; // Character is not found
}
count++;
}
return count;
}
Note that array_to_search must be null-terminated in order to be used together with strchr solution above.
This sounds like your friend was given a trick question. The function gets an array of chars and the length of that array but is required to use strchr() even though that function only works on '\0' terminated strings (and there was not given any guaranty that the array is '\0' terminated).
You might thing that it would be fine to use strchr() on the array anyway and then compare the returned pointer to the given length of the array to check if it went past the end of the array. But there are two problems with that:
If strchr() searches past the end of the array, then you already have Undefined Behavior before getting to the check. The program might have crashed before returning from strchr(), the returned pointer might be some total garbage or you might get a pointer to an address a bit further in memory than the end of the array.
Even if the returned pointer is just to an address a bit further in memory than the end of the array, then there is the problem that comparing two pointers (or subtracting them to find the distance between the pointed addresses) is Undefined Behavior unless they're both pointing to parts of the same memory object (or one position past the end of the object). In this instance it means that checking if the returned pointer is within the bounds of the array is only defined behavior if the returned pointer is within the bounds of the array (or one past the end) making the check a bit useless.
The only solution to that is to make sure that strchr() is working with a '\0' terminated string. For example:
int ch_search(char array_to_search[], char char_to_search_for, int array_size)
{
char *buffer = malloc(array_size + 1);
// Add test here to check if malloc was succesful
strncpy(buffer, array_to_search, array_size);
buffer[array_size] = '\0';
int count = 0;
for (char *i = buffer; (i = strchr(i, char_to_search_for)) != NULL; i++) {
count++;
}
free(buffer);
return count;
}
strchr is a very convenient function to search for a char in a string.
Find and read more about strchr. This is my favorite function ever!
The C library function char *strchr(const char *str, int c) searches for the first occurrence of the character c (an unsigned char) in the string pointed to by the argument str.
Declaration
Following is the declaration for strchr() function.
char *strchr(const char *str, int c)
Parameters
str − This is the C string to be scanned.
c − This is the character to be searched in str.
Return value
Function returns a pointer to the first occurrence of the character c in the string str, or NULL if the character is not found.
Constraints:
1) The arguments are: array to search, character to search for, and
length of the array being searched.
This constrain gives the length of the array to be searched. The given array has to contain '\0' at some point. However the length of search search can be shorter and specified by the search_length.
Following compact solution takes this under account.
int ch_search(char array_to_search[], char char_to_search_for, int search_length)
{
int count = 0;
for(char *p = array_to_search; ;p++)
{
p = strchr(p, char_to_search_for);
if( p != NULL && (p - array_to_search < search_length) )
count++;
else
break;
}
return count;
}
Or equivalent ch_search2:
#include<stdio.h>
#include<string.h>
int ch_search(char array_to_search[], char char_to_search_for, int search_length)
{
int count = 0;
for(char *p = array_to_search; ;p++)
{
p = strchr(p, char_to_search_for);
if( p != NULL && (p - array_to_search < search_length) )
count++;
else
break;
}
return count;
}
// Your original function:
int ch_search1(char array_to_search[], char char_to_search_for, int array_size)
{
int count = 0;
for (int i = 0; i < array_size; i++){
// count each character instance
if (array_to_search[i] == char_to_search_for){
count++; // keep incrementing the count
}
}
return count;
}
int ch_search2(char array_to_search[], char char_to_search_for, int array_size)
{
int count = 0;
char *p = array_to_search;
for(;;)
{
p = strchr(p, char_to_search_for);
if( p != NULL )
{
if (p - array_to_search >= array_size) // we reached beyond
{
break;
}
else
{
count++;
p++;
}
}
else
break; // char not found
}
return count;
}
int main(void)
{
// the arr has to contain '\0' terminator but we can search within the specified length.
char arr[]={'1','1','2','2','1','1','3','3','3','1','4','4', '1','1','!','1','\0','1'};
char arr1[] = "zdxbab";
printf("count %d count %d \n",ch_search(arr , '1', 12),ch_search2(arr , '1', 12));
printf("count %d count %d \n",ch_search(arr1,'b',strlen(arr1)),ch_search2(arr1,'b',strlen(arr1)));
return 0;
}
Output:
count 5 count 5
count 2 count 2

Function that returns 1 if two arrays are completely different and 0 if there's a common element

I've tried this code but it doesn't seem to be working, how to break out of the nested loop ?
#include <stdio.h>
#include <string.h>
int meme(char s1[], char s2[])
{
int i = 0, j = 0;
int different;
while (i <= strlen(s1) && different == 1) {
while (j <= strlen(s2)) {
if (s1[i] != s2[j]) {
different = 1;
} else {
different = 0;
}
j = j + 1;
}
i = i + 1;
}
return different;
}
You have to initialize different as it is undefined if not - this probably breaks your first while loop as different probably is a random number > 1.
strlen gives you the number of characters in the string excluding the null-character which terminates the string (see here). However, you do not only compare the characters of the two strings, but also the null-character, probably to implicitely check if the length of the strings is the same. While this should work, it is better to do this check explicitely by comparing the length of the strings first as it is less error-prone.
It isn't necessary to do a nested loop here if you compare the length of the strings first. Also, you now know the length of both strings, so this function can be change to use a for loop, which makes it even simpler.
A possible solution based on the points above:
#include <stdio.h>
#include <string.h>
int meme(char s1[], char s2[]){
int i = 0;
int len_s1 = 0;
int len_s2 = 0;
int different = 0;
len_s1 = strlen(s1);
len_s2 = strlen(s2);
if (len_s1 == len_s2) {
for (i = 0 ; i < len_s1 ; i++) {
if (s1[i] != s2[i]) {
different = 1;
break;
}
}
else {
different = 1;
}
return different;
}
One more thing - do yourself and everyone else a favor and intend your code as it is extremely hard to read otherwise!
Your code is not optimized and you are not using a good approach for doing the task. I have modified the code and it will do the job with minimized complexity.
Here I assume that both the arrays are of same size as your problem shows
bool meme(char s1[], char s2[])
{
int i=0;
while(s1[i] != NULL && s2[i] != NULL)
{
if(s1[i] == s2[i])
return false;
i += 1;
}
return true;
}
When you call this function then declare a variable of type bool and store the returned value of this function in that variable.
For example :
bool check;
bool = meme(array 1 , array 2);
and then check if returned value is true, then both the arrays are totally different else not. You can do that by the below code :
if(check)
printf("Arrays are different");
else
printf("Arrays are not different");
You can also use int in place of bool if it suits you better but remember, whatever code you write, must be least complex. And think that if you are using int then also you are returning only 0 or 1; but int takes 2 bytes in 32-bit compiler and 4 bytes in 64-bit compiler, but bool takes only 1 byte and even 1 bit in some languages like pascal (if I am not wrong).
And don't get confused with return true; and return false;. True simply means 1 and false means 0. And a boolean type variable can store only binary number (1 or 0).
There is so much wrong with your code.
Why are you calling strlen() in while()? It will get executed every time till the loop doesn't exit and will cost on performance.
Also the variable different is not initialized with value 1, so how can you be so sure about the initial value of that variable?
I have tried to simplify your function still, there is scope for optimization:
int meme(char s1[], char s2[])
{
int i = 0;
int different;
int str1_len = strlen(s1);
int str2_len = strlen(s2);
if(str1_len > str2_len)
str1_len = str2_len;
do{
if(s1[i] == s2[i])
{
printf("Common\n");
different = 0;
}
else
{
different = 1;
}
i++;
}while(str1_len--);
return different;
}

How to find an element in an array of structs in C?

I have to write a function that finds a product with given code from the given array. If product is found, a pointer to the corresponding array element is returned.
My main problem is that the given code should first be truncated to seven characters and only after that compared with array elements.
Would greatly appreciate your help.
struct product *find_product(struct product_array *pa, const char *code)
{
char *temp;
int i = 0;
while (*code) {
temp[i] = (*code);
code++;
i++;
if (i == 7)
break;
}
temp[i] = '\0';
for (int j = 0; j < pa->count; j++)
if (pa->arr[j].code == temp[i])
return &(pa->arr[j]);
}
Why don't you just use strncmp in a loop?
struct product *find_product(struct product_array *pa, const char *code)
{
for (size_t i = 0; i < pa->count; ++i)
{
if (strncmp(pa->arr[i].code, code, 7) == 0)
return &pa->arr[i];
}
return 0;
}
temp is a pointer which is uninitialized and you are dereferencing it which will lead to undefined behavior.
temp = malloc(size); // Allocate some memory size = 8 in your case
One more mistake I see is
if (pa->arr[j].code == temp[i]) // i is already indexing `\0`
should be
strcmp(pa->arr[j].code,temp); // returns 0 if both the strings are same
This code can completely be avoided if you can use strncmp()
As pointed out by others, you are using temp uninitialized and you are always comparing characters with '\0'.
You don't need a temp variable:
int strncmp ( const char * str1, const char * str2, size_t num );
Compare characters of two strings
Compares up to num characters of the
C string str1 to those of the C string str2.
/* Don't use magic numbers like 7 in the body of function */
#define PRODUCT_CODE_LEN 7
struct product *find_product(struct product_array *pa, const char *code)
{
for (int i = 0; i < pa->count; i++) {
if (strncmp(pa->arr[i].code, code, PRODUCT_CODE_LEN) == 0)
return &(pa->arr[i]);
}
return NULL; /* Not found */
}
When you write char* temp; you are just declaring an uninitialized pointer
In your case since you say that the code is truncated to 7 you could create a buffer
on the stack with place for the code
char temp[8];
Writing
temp[i] = (*code);
code++;
i++;
Can be simplified to:
temp[i++] = *code++;
In your loop
for (int j = 0; j < pa->count; j++)
if (pa->arr[j].code == temp[i])
return &(pa->arr[j]);
You are comparing the address of code and the character value of temp[i] which incidentally could be 8 and outside the array.
Instead what you want to do is compare what code points to and what temp contains:
for (int j = 0; j < pa->count; j++)
if (!strncmp(pa->arr[j].code, temp, 7)
return &(pa->arr[j]);
You should also return NULL; if nothing was found, seems you do not return anything.
Probably a good thing is also to make sure your temp[] always contains 7 characters.

Making two arrays the same length. C(89)

The two arrays passed in are constants so I made two new arrays.
The first array stores a group of chars and the second array stores a second group of chars. So far I assume that the first group is bigger than the second ex. (a,b,c,d > x,y).
What the program hopes to accomplish is to make two new arrays that contain the same letters but the shorter array in this case arr2 (newarr2) has it's last char repeated until it matches the length of the first array.
examples of correct solutions.
(a,b,c,d < x,y) --> equate_arr --> (a,b,c,d = x,y,y,y)
void equate_arr(char arg2[], char arg1[]){
size_t i = 0;
size_t len1 = strlen(arg1);
size_t len2 = strlen(arg2);
char newarr2[512];
char newarr1[512];
while(i < (strlen2 - 1))
{
newarr2[i] = arg2[i];
i++;
}
i = 0;
while(i < (strlen1 - 1))
{
newarr1[i] = arg1[i];
i++;
}
i = 0;
while(strlen(newarr2) < strlen(newarr1))
{
newarr2[strlen(newarr2)] = newarr2[strlen(newarr2)-1]
}
}
Currently I have no idea what is happening because once I fiddle with this function in my code the program does not seem to run anymore. Sorry about asking about this project I'm working on so much but I really do need some assistance.
I can put the whole program in here if needed.
Revised
void tr_non_eq(char arg1[], char arg2[], int len1, int len2)
{
int i = 0;
char* arr2;
arr2 = (char*)calloc(len1+1,sizeof(char));
while(i < len2)
{
arr2[i] = arg2[i];
i++;
}
while(len2 < len1)
{
arr2[len2] = arg2[len2-1];
len2++;
}
tr_str(arg1, arr2);
}
Right now with inputs (a,b,c,d,e,f) and (x,y) and a string "cabbage" to translate the program prints out "yxyyx" and with string "abcdef" it prints out "xyy" which shows promise. I am not too sure why the arr2 array does not get filled with "y" chars as intended.
As de-duplicator says, as your code stands it effectively achieves nothing. More importantly, what it tries to do is fraught with peril.
The fact that you use strlen to determine the length of your arguments is a clear indicator that equate_arr does not expect to receive two arrays of char. Instead, it wants two NUL-terminated C-style strings. So the declaration should be more like:
void equate_arr(const char *arg2, const char *arg1)
This makes the contract a little clearer.
But note the return type: void. This says your function will not return any values to the caller. So, how did you plan to return the modified arrays?
The next big peril lies in these lines:
char newarr2[512];
char newarr1[512];
What happens if this function is called with a string which is larger than 511 characters (plus the NUL)? The phrase "buffer overrun" should be jumping out at you here.
What you need is to malloc buffers large enough to hold a duplicate of the longest string passed in. But that raises the question of how you will hand the new arrays back to the caller (remember that void return type?).
There are numerous other problems here, largely down to not having a clear definition of the contract this function is meant to meet.
One more for now while I look more closely
while(strlen(newarr2) < strlen(newarr1))
{
newarr2[strlen(newarr2)] = newarr2[strlen(newarr2)-1]
}
The very first pass through this loop overwrites the terminating NUL in newarr2, which means the next call to strlen is off into undefined behavior as it is completely at the mercy of whatever junk is sitting in your stack.
If you are unclear on C-style strings, take a look at my answer to this question which goes into great detail about them.
The following is whiteboard-code (i.e. not compiled, not tested) which would sort of do what you are wanting to achieve. It's purely for reference
// Pad a string so that it is the same length as another. Padding is done
// by replicating the final character.
//
// #param padThis: A C-style string in a non-constant buffer.
// #param bufLength: The size of the buffer containing padThis
// #param toMatchThis: A (possibly) const C-style string to act
// as a template for length
//
// Pre-conditions:
// - Both padThis and toMatchThis reference NUL-terminated sequences
// of chars
// - strlen(padThis) < bufLength. Violating this will exit the program.
// - strlen(toMatchThis) < bufLength. If not, padThis will be padded
// to bufLength characters.
//
// Post-conditons:
// - The string referenced by toMatchThis is unchanged
// - The original string at padThis has been padded if necessary to
// min(bufLength, strlen(toMatchThis))
void padString(char * padThis, size_t bufLength, const char * toMatchThis)
{
size_t targetLength = strlen(toMatchThis);
size_t originalLength = strlen(padThis);
if (originalLength >= bufLength)
{
fprintf(stderr, "padString called with an original which is longer than the buffer!\n");
exit(EXIT_FAILURE);
}
if (targetLength >= bufLength)
targetLength = bufLength -1; // Just pad until buffer full
if (targetLength <= strlen(padThis))
return; // Nothing to do
// At this point, we know that some padding needs to occur, and
// that the buffer is large enough (assuming the caller is not
// lying to us).
char padChar = padThis[originalLength-1];
size_t index = originalLength;
while (index < targetLength)
padThis[index++] = padChar;
padThis[index] = '\0';
}
Since you declared
char newarr2[512];
char newarr1[512];
as size 512 and not assigned any data, strlen will always return size of newarr1 and newarr2 as garbage since you not ended the string with a proper NULL character.
while(strlen(newarr2) < strlen(newarr1))
{
newarr2[strlen(newarr2)] = newarr2[strlen(newarr2)-1]
}
this while loop will not work properly.
for ( i = len2; i < len1; ++i )
newarr2[i] = newarr2[len2-1]
if len2 is always less than len1, you can use the above loop
if you do not know the which array will be bigger than,
size_t len1 = strlen(arg1);
size_t len2 = strlen(arg2);
char* newarr1;
char* newarr2;
int i;
if ( len1 >= len2 )
{
newarr1 = (char*)calloc(len1+1,sizeof(char));
newarr2 = (char*)calloc(len1+1,sizeof(char));
}
else
{
newarr1 = (char*)calloc(len2+1,sizeof(char));
newarr2 = (char*)calloc(len2+1,sizeof(char));
}
for ( i = 0; i < len1; ++i)
newarr1[i] = arg1[i];
for ( i = 0; i < len2; ++i)
newarr2[i] = arg2[i];
if( len1 >= len2 )
{
for ( i = len2; i < len1; ++i )
newarr2[i] = newarr2[len2-1];
}
else
{
for ( i = len1; i < len2; ++i )
newarr1[i] = newarr1[len1-1];
}
free the memory later

Resources