i am getting error in this c program - c

i am trying to implement this c program , i want to expand strings
eg a-z to a b c d ...z etc
when i put the input string as a-z i dont get the o/p but when i use the input string as az or without using the - i get the desired o/p
#include<stdio.h>
main()
{
char s1[20] = "a z", s2[10], s3[30];
int k = 0, i = 0;
while (s1[i] != '\0')
{
if((s1[i] >= 65 && s1[i]<= 90) || (s1[i] >= 97 && s1[i]<= 122))
s2[k]=s1[i];
i++; k++;
}
s2[k] = '\0';
for (int m = s2[0] ; m <= s2[1] ; m++)
printf("%c ",m);
}

You should only update 'k' position when required:
if((s1[i] >= 65 && s1[i]<= 90) || (s1[i] >= 97 && s1[i]<= 122)) {
s2[k]=s1[i];
k++;
}
i++;
Furthermore your destination array s2 (the one in which you store the expanded letters) shall be of at least 27 size (26+\0).

as per your need:
char s1[20] = "a-z", s2[10],s3[30]; //a-z are now 3 characters
for(int m=s2[0]; m<=s2[2] ; m++) //loop for 3rd character i.e. "z".
printf("%c ",m);
output : a b c d e f g h i j k l m n o p q r s t u v w x y z

Why bother so much? This small piece of code would do what you need:
#include<stdio.h>
int main()
{
char s1[4] = "a-z";
int m;
for(m=s1[0]; m<=s1[2]; m++)
{
printf("%c ",m);
}
return 0;
}

#include <stdio.h>
char *expand(char *out, const char *in){
size_t i, j;
for(j = i = 0; in[i] != '\0'; ++i){
if(in[i] != '-' || i == 0 || in[i+1] == '\0' || (unsigned char)in[i-1] >= (unsigned char)in[i+1]){
out[j++] = in[i];
} else {
unsigned char ch_s = in[i-1] + 1, ch_e = in[i+1];
while(ch_s < ch_e){
out[j++] = ch_s++;
}
}
}
out[j] = '\0';
return out;
}
int main(void){
const char *test[] = {
"a-z", "-a-e", "A-Z0-9", "a-a", "z-a", "a-e-g", "this is test-print"
};
char expanded[128];
size_t i, size = sizeof(test)/sizeof(*test);
for(i = 0; i < size; ++i){
printf("%s expand to %s\n", test[i], expand(expanded, test[i]));
}
return 0;
}
#if 0
a-z expand to abcdefghijklmnopqrstuvwxyz
-a-e expand to -abcde
A-Z0-9 expand to ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
a-a expand to a-a
z-a expand to z-a
a-e-g expand to abcdefg
--/ expand to -./
test-print expand to test-print
#endif

Related

I need to make a program that will print characters in a word on how frequent it is used

I need to make a program that will print characters in a word on how frequent it is used. The unique characters will be printed in increasing order (spaces are ignored), if there are ties the character with lower ascii value will be printed first.
For an example if the input is hello world, the letters "h", "e", "w", "r" and "d" are only used once, the character "o" is used twice and the character "l" is used thrice. Since h,e,w,r,d are tie we should sort it into d,e,h,r,w. Then next would be o since it is used twice and then last is l. Thus if the input is hello world the output must be dehrwol. On my current program the problem is that when there are ties, it would not sort it alphabetically so the output is hewrdol instead of dehrwol.
This is the code I have written
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int times[256];
int cmpLetters(const void* a, const void* b)
{
return (times[*(char*)a] > times[*(char*)b]) - (times[*(char*)a] < times[*(char*)b]);
}
int main()
{
char letters[256];
int i, j, k, lnum, t;
char s[1000];
fgets(s, sizeof(s), stdin);
// Init occurrences as 0
memset(times, 0, sizeof(times));
for (i = lnum = 0; s[i] != '\0'; i++)
if (times[s[i]]++ == 0)
letters[lnum++] = s[i];
// Sort letters by number of occurrences
qsort(letters, lnum, sizeof(char), cmpLetters);
char* new = malloc(sizeof(char) * (i + 1));
for (j = k = 0; j < lnum; j++)
for (i = 0; i < times[letters[j]]; i++)
new[k++] = letters[j];
// new[k] = '\0';
for (i = 0; i<lnum; i++)
{
if(letters[i] != '\n' && letters[i] !=' ')
printf("%c",letters[i]);
}
printf("\n\n");
return 0;
}
In this for loop
for (i = lnum = 0; s[i] != '\0'; i++)
if (times[s[i]]++ == 0)
letters[lnum++] = s[i];
you are not checking whether s[i] represents a letter.
The comparison function
int cmpLetters(const void* a, const void* b)
{
return (times[*(char*)a] > times[*(char*)b]) - (times[*(char*)a] < times[*(char*)b]);
}
compares only characters without comparing also their frequencies.
This code snippet
char* new = malloc(sizeof(char) * (i + 1));
for (j = k = 0; j < lnum; j++)
for (i = 0; i < times[letters[j]]; i++)
new[k++] = letters[j];
does not make sense because the array new is not used further in the program. It only produces a memory leak.
The program will be simpler if to introduce a structure that contains two data members that store a letter and its frequency.
Here is a demonstration program.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct Pair
{
char c;
size_t n;
};
int cmp( const void *a, const void *b )
{
const struct Pair *p1 = a;
const struct Pair *p2 = b;
int result = ( p2->n < p1->n ) - ( p1->n < p2->n );
if (result == 0)
{
result = ( p2->c < p1->c ) - ( p1->c < p2->c );
}
return result;
}
int main( void )
{
enum { N = 1000} ;
char s[N];
fgets( s, sizeof( s ), stdin );
size_t n = 0;
for (size_t i = 0; s[i] != '\0'; ++i)
{
if (isalpha( ( unsigned char )s[i] ))
{
size_t j = 0;
while (j != i && s[j] != s[i]) ++j;
n += j == i;
}
}
if (n != 0)
{
struct Pair pairs[n];
memset( pairs, 0, n * sizeof( struct Pair ) );
for (size_t i = 0, m = 0; s[i] != '\0'; i++)
{
if (isalpha( ( unsigned char )s[i] ))
{
size_t j = 0;
while (j != m && pairs[j].c != s[i]) ++j;
if (j == m)
{
pairs[m].c = s[i];
++pairs[m].n;
++m;
}
else
{
++pairs[j].n;
}
}
}
qsort( pairs, n, sizeof( *pairs ), cmp );
for (size_t i = 0; i < n; i++)
{
putchar( pairs[i].c );
}
putchar( '\n' );
}
}
The program output might look like
hello world
dehrwol

Palindrome/mini-Palindrome in string

I need to check if a given string is a Palindrome or mini-Palindrome.
Palindrome length will be 2 or more, the function need to ignore spaces and ignore the differences of upper and lower alphabet.
if the string is Palindrome the function will transfer the indexes of the start and the end of him and will return 1 else return 0.
example1: "My gym" the function will transfer low=0 high=5 and 1
example2: "I Love ANNA" the function will transfer low=7 high=10 and 1
example3: "I love Pasta" return 0.
Also i can’t use functions from librarys other then string.h stdlib.h stdio.h.
I tried to write like this:
int i;
int size = strlen(str);
i = 0;
while (str[i] != '\0')
{
if (str[i] == ' ')
{
i++;
continue;
}
//-------------------
if (str[i] >= ‘a’ && str[i] <= ‘z’)
str[i] = str[i] - 32;
if (str[size-1] >= ‘a’ && str[size-1] <= ‘z’)
str[size-1] = str[size-1] - 32;
//-------------------
if (str[i] == str[size-1])
{
*low = i;
*high = size-1;
return 1;
}
else
{
size--;
i++;
}
}
return 0;
But it isnt working well, i cant figure how to do it with the example 2
Here goes. Will this help you
#define LOWER(a) (((a) >=' A' && (a) <= 'Z') ? ((a) - 'A' +'a') : (a))
#define MYCMP(a,b) (LOWER(a) == LOWER(b))
int is_palidrome(char *s) {
int start = 0;
int end = strlen(s) - 1;
for (; s[start] // Not end of line
&& end >=0 // Not run over the from of the line
&& start < end // Still not got to the middle
&& MYCMP(s[start], s[end]) == 1; // They are still equal
start++, end--) { //Nowt }
};
return (start >= end);
}
I made a program. It works only if the string contains letters and spaces. You can modify it to work for other characters.
#include <stdio.h>
#include <string.h>
#define SIZE 100
int isPalindrome( char *s, size_t l );
int main() {
char str[SIZE];
size_t i, j, len, pldrm = 0;
fgets(str, SIZE, stdin);
len = strlen(str);
for(i = 0; i < len; i++) if( str[i] != ' ' && !((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')) ) goto the_end;
for(i = 0; i < len-1; i++) {
if( str[i] != ' ' ) {
for(j = i+1; j < len; j++) {
if( (pldrm = isPalindrome(&str[i], j-i+1)) ) {
str[j+1] = '\0';
goto the_end;
}
}
}
}
the_end:
pldrm ? printf("A palindrome has been found from the position %zu till the position %zu.\n\nThe palindrome is: %s\n", i, j, &str[i]) : puts("No palindromes");
return 0;
}
int isPalindrome( char *s, size_t l )
{
static const char az[26] = "abcdefghijklmnopqrstuvwxyz", AZ[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int isPldrm = 1, spc = 0; // used to skip spaces within the palindrome
for(size_t i = 0; i < l/2; i++) {
for(size_t j = 0; j < 26; j++) {
if( s[i] == az[j] || s[i] == AZ[j] ) {
while( s[l-1-i-spc] == ' ' ) ++spc;
if( s[l-1-i-spc] != az[j] && s[l-1-i-spc] != AZ[j] ) {
isPldrm = 0;
goto thats_it;
}
break;
}
}
}
thats_it:
return isPldrm;
}
Also, it finds only the first palindrome in the input. Doesn't check for further palindromes.

Different output in Windows and Linux (gcc) C compilers

I have a program which solves maze, so that it finds possible route from Start(S) to Exit(E).Here is my Maze:
1111S11110
0000010001
110100010d
t001111110
0100000001
0111111101
1111111101
00000D01T1
0111110001
0000E01110
The possible route to it is :
Start S W W S S S E E E E E E S S S S W W N W W W W W W S S E E E E Exit
which is correct and i get it on CodeBlocks, However when i compile my code on dev through putty i get this:
Start S S S S S W N N W S W N N N W N Exit
Here is my whole code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// Global Variables for use
int matrixSize,startX,startY,exitX,exitY;
char src[1500] = " ";
char Ndirection[50] = " N ";
char Sdirection[50] = " S ";
char Edirection[50] = " E ";
char Wdirection[50] = " W ";
// Function for finding the array length
int numOfLines(FILE *const mazeFile) {
int c, count;
count = 0;
for (;; ) {
c = fgetc(mazeFile);
if (c == EOF)
break;
if (c == '\n')
++count; // end of line => increment line counter
}
rewind(mazeFile);
return count+1;
}
int capLetter(char ch){
int result = 0;
if(ch >= 'A' && ch <= 'Z'){
result = 1;
}
return result;
}
int lowLetter(char ch){
int result = 0;
if(ch >= 'a' && ch <= 'z'){
result = 1;
}
return result;
}
int isSafe(char Mazearray[matrixSize][matrixSize],int x,int y){
if(x >= 0 && x < matrixSize && y >= 0 && y < matrixSize && Mazearray[x][y] != '1'){
return 1;
}
return 0;
}
void MazeSolution(char Mazearray[matrixSize][matrixSize],int x,int y,char pathArray[matrixSize][matrixSize],char wasHereArray[matrixSize][matrixSize]){
if(recursiveMaze(Mazearray,x,y,pathArray,wasHereArray) == 0){
printf("There does not exist a possible solution!!!");
}
else{
pathArray[startX][startY] = 'S';
}
}
int recursiveMaze(char Mazearray[matrixSize][matrixSize],int x,int y,char pathArray[matrixSize][matrixSize],char wasHereArray[matrixSize][matrixSize]){
if(x == startX && y == startY){
pathArray[x][y] = 'S';
}
if(x == exitX && y == exitY){
pathArray[x][y] = 'E';
return 1;
}
// check if the coordinate is safe to go(not 1)
if(isSafe(Mazearray,x,y) == 1 && wasHereArray[x][y] != '1'){
wasHereArray[x][y] = '1';
// Move North
if(recursiveMaze(Mazearray,x-1,y,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Ndirection);
return 1;
}
// Move South
if(recursiveMaze(Mazearray,x+1,y,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Sdirection);
return 1;
}
// Move East
if(recursiveMaze(Mazearray,x,y+1,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Edirection);
return 1;
}
// Move West
if(recursiveMaze(Mazearray,x,y-1,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Wdirection);
return 1;
}
}
return 0;
}
// Main Function
int main( int argc, char **argv )
{
// Opening the Matrix File
FILE *mazeFile;
mazeFile = fopen(argv[1], "r" );
if( mazeFile == NULL )
return 1;
matrixSize = numOfLines( mazeFile );
// Reading text file into 2D array
int i,j;
char mazeArray [matrixSize][matrixSize];
for (i = 0; i<matrixSize; i++) {
for (j = 0; j<matrixSize; j++) {
fscanf(mazeFile, "%c", &mazeArray[i][j]);
}
char eol;
fscanf(mazeFile, "%c", &eol);
}
// Variables
//Creating path array
char pathArray[matrixSize][matrixSize];
for (i = 0; i < matrixSize; i++){
for (j = 0; j < matrixSize; j++){
pathArray[i][j] = '0';
}
}
// CheckPoint array
char wasHereArray[matrixSize][matrixSize];
for (i = 0; i < matrixSize; i++){
for (j = 0; j < matrixSize; j++){
wasHereArray[i][j] = '0';
}
}
// Finding start and exit indexes
for (i = 0; i<matrixSize; i++) {
for (j = 0; j<matrixSize; j++) {
if(mazeArray[i][j] == 'S'){
startX = i;
startY = j;
}
if(mazeArray[i][j] == 'E'){
exitX = i;
exitY = j;
}
}
}
MazeSolution(mazeArray,startX,startY,pathArray,wasHereArray);
char *data = src;
int length=strlen(data);
char bytes[length];
int n=0;
while(n<=length)
{
bytes[n] = data[length-n-1];
n++;
}
FILE *f = fopen("path.txt", "w");
fprintf(f, "Start %s Exit",bytes);
fclose(mazeFile);
fclose(f);
return 0;
}
I don't know what is wrong and where to start?
DOS line endings are CR-LF ("\r\n") and *nix line endings are just LF ("\n"). Change these lines main:
char eol;
fscanf(mazeFile, "%c", &eol);
to:
int c = fgetc(mazefile); // Slurp a '\r' carriage return or '\n' linefeed character.
if ('\r' == c) {
c = fgetc(mazefile); // slurp the '\n' linefeed character.
}

Sorting words out in a string array

My program is designed to allow the user to input a string and my program will output the number of occurrences of each letters and words. My program also sorts the words alphabetically.
My issue is: I output the words seen (first unsorted) and their occurrences as a table, and in my table I don't want duplicates. SOLVED
For example, if the word "to" was seen twice I just want the word "to" to appear only once in my table outputting the number of occurrences.
How can I fix this? Also, why is it that i can't simply set string[i] == delim to apply to every delimiter rather than having to assign it manually for each delimiter?
Edit: Fixed my output error. But how can I set a condition for string[i] to equal any of the delimiters in my code rather than just work for the space bar? For example on my output, if i enter "you, you" it will out put "you, you" rather than just "you". How can I write it so it removes the comma and compares "you, you" to be as one word.
Any help is appreciated. My code is below:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char delim[] = ", . - !*()&^%$##<> ? []{}\\ / \"";
#define SIZE 1000
void occurrences(char s[], int count[]);
void lower(char s[]);
int main()
{
char string[SIZE], words[SIZE][SIZE], temp[SIZE];
int i = 0, j = 0, k = 0, n = 0, count;
int c = 0, cnt[26] = { 0 };
printf("Enter your input string:");
fgets(string, 256, stdin);
string[strlen(string) - 1] = '\0';
lower(string);
occurrences(string, cnt);
printf("Number of occurrences of each letter in the text: \n");
for (c = 0; c < 26; c++){
if (cnt[c] != 0){
printf("%c \t %d\n", c + 'a', cnt[c]);
}
}
/*extracting each and every string and copying to a different place */
while (string[i] != '\0')
{
if (string[i] == ' ')
{
words[j][k] = '\0';
k = 0;
j++;
}
else
{
words[j][k++] = string[i];
}
i++;
}
words[j][k] = '\0';
n = j;
printf("Unsorted Frequency:\n");
for (i = 0; i < n; i++)
{
strcpy(temp, words[i]);
for (j = i + 1; j <= n; j++)
{
if (strcmp(words[i], words[j]) == 0)
{
for (a = j; a <= n; a++)
strcpy(words[a], words[a + 1]);
n--;
}
} //inner for
}
i = 0;
/* find the frequency of each word */
while (i <= n) {
count = 1;
if (i != n) {
for (j = i + 1; j <= n; j++) {
if (strcmp(words[i], words[j]) == 0) {
count++;
}
}
}
/* count - indicates the frequecy of word[i] */
printf("%s\t%d\n", words[i], count);
/* skipping to the next word to process */
i = i + count;
}
printf("ALphabetical Order:\n");
for (i = 0; i < n; i++)
{
strcpy(temp, words[i]);
for (j = i + 1; j <= n; j++)
{
if (strcmp(words[i], words[j]) > 0)
{
strcpy(temp, words[j]);
strcpy(words[j], words[i]);
strcpy(words[i], temp);
}
}
}
i = 0;
while (i <= n) {
count = 1;
if (i != n) {
for (j = i + 1; j <= n; j++) {
if (strcmp(words[i], words[j]) == 0) {
count++;
}
}
}
printf("%s\n", words[i]);
i = i + count;
}
return 0;
}
void occurrences(char s[], int count[]){
int i = 0;
while (s[i] != '\0'){
if (s[i] >= 'a' && s[i] <= 'z')
count[s[i] - 'a']++;
i++;
}
}
void lower(char s[]){
int i = 0;
while (s[i] != '\0'){
if (s[i] >= 'A' && s[i] <= 'Z'){
s[i] = (s[i] - 'A') + 'a';
}
i++;
}
}
I have the solution to your problem and its name is called Wall. No, not the type to bang your head against when you encounter a problem that you can't seem to solve but for the Warnings that you want your compiler to emit: ALL OF THEM.
If you compile C code with out using -Wall then you can commit all the errors that people tell you is why C is so dangerous. But once you enable Warnings the compiler will tell you about them.
I have 4 for your program:
for (c; c< 26; c++) { That first c doesn't do anything, this could be written for (; c < 26; c++) { or perhaps beter as for (c = 0; c <26; c++) {
words[i] == NULL "Statement with no effect". Well that probably isn't what you wanted to do. The compiler tells you that that line doesn't do anything.
"Unused variable 'text'." That is pretty clear too: you have defined text as a variable but then never used it. Perhaps you meant to or perhaps it was a variable you thought you needed. Either way it can go now.
"Control reaches end of non-void function". In C main is usually defined as int main, i.e. main returns an int. Standard practice is to return 0 if the program successfully completed and some other value on error. Adding return 0; at the end of main will work.
You can simplify your delimiters. Anything that is not a-z (after lower casing it), is a delimiter. You don't [need to] care which one it is. It's the end of a word. Rather than specify delimiters, specify chars that are word chars (e.g. if words were C symbols, the word chars would be: A-Z, a-z, 0-9, and _). But, it looks like you only want a-z.
Here are some [untested] examples:
void
scanline(char *buf)
{
int chr;
char *lhs;
char *rhs;
char tmp[5000];
lhs = tmp;
for (rhs = buf; *rhs != 0; ++rhs) {
chr = *rhs;
if ((chr >= 'A') && (chr <= 'Z'))
chr = (chr - 'A') + 'a';
if ((chr >= 'a') && (chr <= 'z')) {
*lhs++ = chr;
char_histogram[chr] += 1;
continue;
}
*lhs = 0;
if (lhs > tmp)
count_string(tmp);
lhs = tmp;
}
if (lhs > tmp) {
*lhs = 0;
count_string(tmp);
}
}
void
count_string(char *str)
{
int idx;
int match;
match = -1;
for (idx = 0; idx < word_count; ++idx) {
if (strcmp(words[idx],str) == 0) {
match = idx;
break;
}
}
if (match < 0) {
match = word_count++;
strcpy(words[match],str);
}
word_histogram[match] += 1;
}
Using separate arrays is ugly. Using a struct might be better:
#define STRMAX 100 // max string length
#define WORDMAX 1000 // max number of strings
struct word {
int word_hist; // histogram value
char word_string[STRMAX]; // string value
};
int word_count; // number of elements in wordlist
struct word wordlist[WORDMAX]; // list of known words

Trying to compare two strings

It is sufficient to say that I am new to C so please have show some mercy ;).
I'm trying to compare two strings. The output shouldn't contain common characters. Sadly it does.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
const char msg[15] = "blueberry";
int c;
int s[15];
int j = 0;
int i = 0;
int k= 0;
int ok = 0;
int t = 0;
while (i < 15 && (c = getchar()) != '\n')
{
s[i] = c;
++i;
}
for (t=j=0; t < 15; ++t)
{
ok = 1;
//printf ("%c", s[t]);
}
for (k=0; msg[k] != '\0'; ++k)
{
if (s[t] == msg[k])
{
ok = 0;
}
}
if (ok == 1)
{
s[j] = s[t];
j++;
}
s[j] = '\0';
for (j = 0; j < 15; ++j)
printf ("%c ", s[j]);
}
The input from the keyboard is blackberry, expected output should've been U but sadly it is not. Any help please. Also why is it entering the nested for loop irrespective of condition?
My big thanks to everyone, it helped me a lot. I've figured out a way & am ok with the output. I've borrowed some ideas from A4L :).
To compare two string, you can use strcmp().
The following is a string compare program that you can use for your reference. I has both array and pointer version for better understanding.
#include <stdio.h>
int strcmp1(char a[], char b[])
{
int i=0;
while (a[i] == b[i]) {
if (a[i] == '\0')
return 0;
i++;
}
return a[i]-b[i];
}
int strcmp2(char *a, char *b)
{
while (*a == *b) {
if (*a == '\0')
return 0;
a++; b++;
}
return *a-*b;
}
int main()
{
char s1[] = "test string1";
char s2[] = "test string";
char s3[] = "aaa";
char s4[] = "bbb";
printf("strcmp1(%s, %s) = %d \n", s1, s2, strcmp1(s1, s2));
printf("strcmp2(%s, %s) = %d \n", s3, s4, strcmp2(s3, s4));
return 0;
}
given that msg contains "blueberry" and s contains "blackberry" this should do it
for (int i=0; i < strlen(msg); i++) {
for (int j = 0; j < strlen(s); j++) {
if (msg[i] != s[j]) {
printf ("%c", msg[i]);
}
}
}
yes it's ugly (using the strlen in the for gives me the chills, but I'm still low on coffeine today ^^)
i guess you want to find the first letter where the input differs from message
here is your own code with some fixes
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char msg[15] = "blueberry";
int c;
char s[15];
int i = 0;
int k= 0;
int ok = 0;
while (i < 15 && (c = getchar()) != '\n')
{
s[i] = (char) c;
++i;
}
// make sure to terminate the string after hitting enter
s[i] = '\0';
printf("input: %s\n", s);
printf("messg: %s\n", msg);
// run through both input and message with one counter
for (k=0; ok == 0 && msg[k] != '\0' && s[k] != '\0'; )
{
// if different chars stop
if (s[k] != msg[k]){
ok = 1;
} else {
// next char
k++;
}
}
if (ok == 1)
{
printf ("diff # index %d -> %c\n", k, msg[k]);
}
else
{
printf ("no diff\n");
}
return 0;
}
#include <stdio.h>
#include <string.h>
//Length to match
int comm(char* s1, char* s2){
int len = 0;
while(*s1 && *s2 && *s1++ == *s2++)
++len;
return len;
}
//commdiffcomm
/*
int commr(char* s1, char* s2){
int len = 0, limit;
int len1,len2;
len1 = strlen(s1);
len2 = strlen(s2);
limit = len1 > len2 ? len2 : len1;
s1 = s1 + len1;
s2 = s2 + len2;
while(limit-- && *--s1 == *--s2)
++len;
return len;
}
//bad
int diff(char* s1, char* s2, int* len1, int* len2){
int len, lenr, s1_len, s2_len, wk_max, i, j;
len = comm(s1, s2);
if(strcmp(s1, s2)==0){
*len1 = *len2 = 0;
return len;
}
lenr = commr(s1, s2);
*len1 = strlen(s1) - len - lenr;
*len2 = strlen(s2) - len - lenr;
return len;
}
*/
int diff(char* s1, char* s2, int* len1, int* len2){
int len, s1_len, s2_len, wk_max, i, j;
len = comm(s1, s2);
if(strcmp(s1, s2)==0){
*len1 = *len2 = 0;
return len;
}
s1_len = strlen(s1 + len + 1);
s2_len = strlen(s2 + len);
wk_max = 0;
for(i = 1; i < s1_len ; i++){
for(j = 0; j < s2_len; j++){
int com_len;
com_len = comm(s1 + len + i, s2 + len + j);
if(wk_max < com_len){
wk_max = com_len;
*len1 = i;
*len2 = j;
}
}
}
return len;
}
int main(){
char str1[16] = "blueberry";
char str2[16] = "blackberry";
char dif1[16] = "";
char dif2[16] = "";
int len0;//length of top to diff pos
int len1;
int len2;
len0 = diff(str1, str2, &len1, &len2);
strncpy(dif1, str1 + len0, len1);
strncpy(dif2, str2 + len0, len2);
if(len1 !=0 && len2 != 0){
printf("%s different %s at position %d length %d (\"%s\")\n", str1, str2, len0, len1, dif1);
printf("%s different %s at position %d length %d (\"%s\")\n", str2, str1, len0, len2, dif2);
} else {
printf("two string is same.");
}
return 0;
}
/*
blueberry different blackberry at position 2 length 2 ("ue")
blackberry different blueberry at position 2 length 3 ("ack")
*/
There are a few problems with the code as is:
You don't null-terminate your input string. Attempting to use it with c string functons would spell trouble. To fix that, change
while (i < 15 && (c = getchar()) != '\n')
{
s[i] = c;
++i;
}
to
while (i < 14 && (c = getchar()) != '\n')
{
s[i] = c;
++i;
}
s[i] = '\0';
Your specification is unclear as to whether you want your program to print the letters unique to msg, or to both s and msg. (i.e, do you want msg-s or (msg ∪ s)-(msg ∩ s) Assuming the first, the important part of your program goes like this:
k=0;
for(i=0;i<strlen(msg);i++){
int exists = 0;
for(j=0;!exists && j<strlen(s);j++){
if(msg[j] == s[i])
exists = 1;
}
if(!exists)
msg[k++] = msg[i];
}
s[k] = '\0';
The inner loop checks if s contains the current character in msg. If it does, we don't do anything, but if it doesn't, we append it to the end of a sublist we're creating on top of the bits of msg we've already processed.
your code is a mess even after the rewrite - there are too many errors to describe in detail
/*
blackbery
b l u e b e r r y
. . a c k b e . .
result = non-equal
*/
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char msg[15] = "blueberry";
int c, s[15], i,j,k, ok;
for (i=0; i < 15; i++) s[i] = 0;
for (i=0; i < 15 && (c = getchar()) != '\n'; i++) s[i] = c;
for (ok=1, k=0; msg[k] != '\0'; ++k)
if (s[k] != msg[k]) ok = 0; else s[k] = '.';
for (j = 0; j < 15; ++j) printf ("%c ", msg[j]);
printf("\n");
for (j = 0; j < 15; ++j) printf ("%c ", s[j]);
printf("\nresult = %s\n", ok ? "equal" : "non-equal");
}

Resources