Reputation: 87
I've been staring at this code for quite awhile and I can't find out what's wrong with this code and how to fix it. I think one of the arrays is being written past whats been allocated.
The debugger is allowing me to compile, but when I do, I get:
Unhandled exception at 0x774615de in HW6_StringProcessing.exe: 0xC0000005: Access violation.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STR_SIZE 100
void convertToPigLatin (char * strPtr, char * pStrPtr);
int main(int argc, char *argv[])
{
char str[MAX_STR_SIZE];
char pStr[MAX_STR_SIZE];
FILE *fileInPtr; //Create file name
FILE *fileOutPtr;
fileInPtr = fopen("pigLatinIn.txt", "r"); //Assign text to file
fileOutPtr = fopen("pigLatinOut.txt", "w");
if(fileInPtr == NULL) //Check if file exists
{
printf("Failed");
exit(-1);
}
fprintf(fileOutPtr, "English Word\t\t\t\tPig Latin Word\n");
fprintf(fileOutPtr, "---------------\t\t\t\t----------------\n");
while(!feof(fileInPtr)) //Cycles until end of text
{
fscanf(fileInPtr, "%99s", str); //Assigns word to *char
str[99] = '\0'; //Optional: Whole line
convertToPigLatin(str, pStr);
//fprintf(fileOutPtr, "%15s\t\t\t\t%15p\n", str, pStr);
printf("%s\n", str);
}
system("pause");
}
void convertToPigLatin (const char * strPtr, char * pStrPtr)
{
int VowelDetect = 0;
int LoopCounter = 0;
int consonantCounter = 0;
char cStr[MAX_STR_SIZE] = {'\0'};
char dStr[] = {'-','\0'};
char ayStr[] = {'a','y','\0'};
char wayStr[] = {'w','a','y','\0'};
while (*strPtr != '\0')
{
if (*strPtr == 'a' || *strPtr == 'e' ||
*strPtr == 'i' || *strPtr == 'o' ||
*strPtr == 'u' || VowelDetect ==1)
{
strncat(pStrPtr, strPtr, 1);
VowelDetect = 1;
}
else
{
strncat(cStr, strPtr, 1);
consonantCounter++;
}
*strPtr++;
}
strcat(pStrPtr, dStr);
if (consonantCounter == 0)
{
strcat(pStrPtr, wayStr);
}
else
{
strcat(cStr,ayStr);
strcat(pStrPtr, cStr);
}
printf("%s\n", pStrPtr);
}
Upvotes: 0
Views: 164
Reputation: 4363
Here's an annotated, working version with some changes and suggestions. You'll probably want to toss the final printf
, but I wanted to make sure there was visible output on the first run. The intent here is to
stay close to the question's actual code, not to rewrite it entirely.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define XSTR(n) #n // a hack to allow stringify to use the *value of a macro
#define STR(n) XSTR(n)
#define MAX_STR_SIZE 100
void convertToPigLatin (const char * strPtr, char * pStrPtr);
int main(int argc, char *argv[])
{
// The str and pStr aren't very meaningful, I'd suggent eng and pig.
// Adding -"Str" to all your strings just slows down reading.
// - plus it makes "str" an anomaly.
char str[MAX_STR_SIZE + 1]; // +1 since NUL is usually not counted..
char pStr[MAX_STR_SIZE + 1]; // ...by functions like strlen().
FILE *fileInPtr = fopen("pigLatinIn.txt", "r"); //Assign text to file
FILE *fileOutPtr = fopen("pigLatinOut.txt", "w");
const char *fmt = "%15s %s\n"; // for head and table output.
if( ! (fileInPtr && fileOutPtr)) {
perror("unable to open file(s) for I/O")
return -1;
}
fprintf(fileOutPtr, fmt, "English Word", "Pig Latin Word");
fprintf(fileOutPtr, fmt, "------------", "---------------");
// put test before fscanf so we don't lose the last input line on EOF
while(!feof(fileInPtr)) //Cycles until end of text
{
if(1 == fscanf(fileInPtr, "%" STR(MAX_STR_SIZE) "s", str))
{
str[MAX_STR_SIZE] = '\0'; //Optional: Whole line
convertToPigLatin(str, pStr);
fprintf(fileOutPtr, fmt, str, pStr);
}
// else fprintf(stderr, "skipping empty line\n"); // for example.
}
// system("pause") would be... icky, sleep(...) or
// getchar() are better, but still odd since output is going
// to a file
fclose(fileInPtr);
fclose(fileOutPtr);
return 0; // a zero exit status from main() means success :-)
}
void convertToPigLatin (const char * strPtr, char * pStrPtr)
{
int VowelDetected = 0;
int LoopCounter = 0;
int ConsonantCounter = 0;
char cStr[MAX_STR_SIZE + 1] = {'\0'};
char dStr[] = "-"; // same as {'-','\0'};
char ayStr[] = "ay"; // same as {'a','y','\0'};
char wayStr[] = "way"; // same as {'w','a','y','\0'};
pStrPtr[0] = '\0'; // clear out pStr so trash doesn't prefix output.
// a better loop control would be: for( /*prior*/ ; *strPtr ; ++strPtr)
// - which lets you move the strPtr++ to the top line of the for loop.
while (*strPtr != '\0') // could simplify to: while(*strPtr)
{
#if 0 // disabling this to show a different option in the #else clause
if ( *strPtr == 'a'
|| *strPtr == 'e'
|| *strPtr == 'i'
|| *strPtr == 'o'
|| *strPtr == 'u'
|| VowelDetected == 1)
{
#else
if (strchr("aeiou", *strPtr) || VowelDetected == 1)
{
#endif
strncat(pStrPtr, strPtr, 1);
VowelDetected = 1;
}
else
{
strncat(cStr, strPtr, 1);
ConsonantCounter++;
}
++strPtr; // a *strPtr++ would increment the target char itself.
}
strcat(pStrPtr, dStr);
if (ConsonantCounter == 0) // or: if( ! Consonantcounter)
{
strcat(pStrPtr, wayStr);
}
else
{
strcat(cStr,ayStr);
strcat(pStrPtr, cStr);
}
printf("# %s\n", pStrPtr);
}
Upvotes: 0
Reputation: 122391
I think the issue might be the use of strcat()
and strncat()
to a buffer which hasn't been initialised. Before calling convertToPigLatin()
, ensure you blat pStr[]
with memset()
or some such:
while(!feof(fileInPtr)) {
...
str[99] = '\0';
pStr[0] = '\0'; // or memset(pStr, 0, sizeof(pStr));
convertToPigLatin(str, pStr);
...
}
Upvotes: 1
Reputation: 41017
Prototype is:
void convertToPigLatin (char * strPtr, char * pStrPtr);
but this function expects const char *
void convertToPigLatin (const char * strPtr, char * pStrPtr)
----------------------------------------^ here
Also, you have to increment the pointer itself (not the value) of strPtr
in convertToPigLatin
*strPtr++;
should be:
strPtr++;
Upvotes: 0
Reputation: 7225
The decleration:
void convertToPigLatin (char * strPtr, char * pStrPtr);
is not consistent with the definition of the function:
void convertToPigLatin (const char * strPtr, char * pStrPtr)
{
...
}
Upvotes: 0