I don\'t know what is the problem in my code, but when I compile I get:
warning: passing arg 2 of `strcspn\' makes pointer from integer without a cast
strcspn(const char *str1, const char *str2) looks for the first instance of any characters in the second string in the first string. You are passing a character instead of a string as the second argument. You want the function strchr(const char *string, int character), which looks for a single character.
The strcspn()
function takes two strings as arguments, but you're passing a string and a character. You need to convert the character into a string somehow. One way to do that would be:
int sep[2] = "";
sep[0] = letter2;
string[strcspn(string, sep)] = letter3;
sep[0] = letter3;
string[strcspn(string, sep)] = letter2;
However, the first call changes the first occurrence of letter2
to letter3
; the second call changes the first occurrence of letter3
(which might be the one just replaced in the previous call) with letter2
. This is not a complete job of transforming the strings — you need to scan the whole string making the changes.
One possibility is this:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#define NULL_VALUE '\0'
static inline void map(char *str, int len, int c_old, int c_new)
{
for (int i = 0; i < len; i++)
{
if (str[i] == c_old)
str[i] = c_new;
}
}
int main(void)
{
char buffer[4096];
printf("Enter a sentence: ");
if (fgets(buffer, sizeof(buffer), stdin) == 0)
return 0;
int length = strlen(buffer);
if (length > 0)
buffer[--length] = '\0';
putchar('\n');
printf("Original [%s]\n", buffer);
int count[256] = { 0 };
for (int i = 0; i < length; i++)
{
if (isalpha((unsigned char)buffer[i]))
count[(unsigned char)buffer[i]]++;
}
int max1_count = 0;
int max2_count = 0;
char max1_value = '\0';
char max2_value = '\0';
for (int i = 0; i < 256; i++)
{
if (count[i] > max1_count)
{
max2_count = max1_count;
max2_value = max1_value;
max1_count = count[i];
max1_value = i;
}
else if (count[i] > max2_count)
{
max2_count = count[i];
max2_value = i;
}
}
/*
** Since a string is a sequence of non-null character codes followed
** by a null byte, it is safe to use '\0' as the temporary value in
** the three-step swap operation
*/
if (max2_count > 0)
{
map(buffer, length, max1_value, NULL_VALUE);
map(buffer, length, max2_value, max1_value);
map(buffer, length, NULL_VALUE, max2_value);
}
printf("Revised [%s]\n", buffer);
return 0;
}
The only reason for using the macro NULL_VALUE
is so that the symmetry of the three map()
lines is self-evident.
I called the program ccswap19
, and I used Bash 'here strings' to supply the data — the putchar('\n');
means that the output appears on a separate line from the prompt. There'd be a blank line before the 'Original' printing if you ran the program interactively.
$ ccswap19 <<< "The hidden costs of the exodus are now revealed for all to see."
Enter a sentence:
Original [The hidden costs of the exodus are now revealed for all to see.]
Revised [Tho hiddon cests ef tho oxedus aro new rovoalod fer all te soo.]
$ ccswap19 <<< "aaaaaaaaaaaa"
Enter a sentence:
Original [aaaaaaaaaaaa]
Revised [aaaaaaaaaaaa]
$ ccswap19 <<< "aaaabaaaaaaa"
Enter a sentence:
Original [aaaabaaaaaaa]
Revised [bbbbabbbbbbb]
$