I'm getting an error (unhandled exception writing address so and so) trying to modify a string. It gets weirder though. Let me show what i've got:

--Main.c--

#include "stdafx.h"
#include "commands.h"

int main(int argc, char* argv[])
{
	char word[256];
	int id;

	strcpy(word, "move");
	strToUpper(word);
	printf("%s", word);
	id = getCommandId(word);

	if(id == -1)
		perror("Error");
	else if(id == 0)
		printf("No such command.");
	else
		printf("ID: %d\n", getCommandId("move"));

	getchar();
	return 0;
}

--commands.h--

#pragma once

#define COMMAND_MOVE 1
#define COMMAND_TAKE 2
#define COMMAND_LOOK 3

int getCommandId(char *word);
void strToUpper(char *str);

And --commands.c--

#include "stdafx.h"
#include "commands.h"

void strToUpper(char *str)
{
	int i = 0;
	while(str[i] != '\0')
	{
		str[i++] &= 0xDF; //reset bit 5
	}
}

int getCommandId(char *word)
{
	FILE *fp;
	char buf[256];
	char *tok;
	int i = 0;

	fp = fopen("commands.dat", "r");
	if(fp == NULL)
		return -1;
	
	strToUpper(word);

	while(++i)
	{
		if(fgets(buf, 255, fp) == NULL)
			break;

		tok = strtok(buf, " ");
		while(tok != NULL)
		{
			if(strcmp(tok, word) == 0)
				return i;

			tok = strtok(NULL, " ");
		}
	}

	return 0;
}

Nothing real exciting happens with the call to strToUpper in main, other than the string being capitalized. Then getCommandId is called, and therefore strToUpper is too, with the same pointer word as before. Only this time, I get the nasty error described at the top of my post. Thoughts?

>>str[i++] &= 0xDF; //reset bit 5
Programming is not about trying to be cute, but about writing code that you and everyone else in the world can easily comprehend. str[i] = toupper(str[i]); ++i;

"Being cute" was not my intention. I was thinking of efficiency at the time. And while I appreciate the suggestion, it doesn't help my immediate problem.

Do you still get the error if you remove:
* the file stuff? (replace it with a single buf load to tokenize)
* the token stuff?
Post a single file minimal version that recreates the error.

I put your program all in one file and here is the result (using VC ++ 2008 Express)

#include <ctype.h>
#pragma warning(disable: 4996)


void strToUpper(char *str)
{
	int i = 0;
	while(str[i] != '\0')
	{
		str[i] = toupper(str[i]); //reset bit 5
        ++i;
	}
}

int getCommandId(char *word)
{
	FILE *fp;
	char buf[256];
	char *tok;
	int i = 0;

	fp = fopen("commands.txt", "r");
	if(fp == NULL)
		return -1;
	
	strToUpper(word);
    i = 0;
	while(fgets(buf, 255, fp) != NULL)
	{
        strToUpper(buf);
		tok = strtok(buf, " ");
        ++i;
		while(tok != NULL)
		{
			if(strcmp(tok, word) == 0)
				return i;

			tok = strtok(NULL, " ");
		}
	}

	return 0;
}

int main(int argc, char* argv[])
{
	char word[256];
	int id;

	strcpy(word, "move");
	strToUpper(word);
	printf("%s", word);
	id = getCommandId(word);

	if(id == -1)
		perror("Error");
	else if(id == 0)
		printf("No such command.");
	else
		printf("ID: %d\n", getCommandId("move"));

	getchar();
	return 0;
}

The main problem with the program is that main() calls getComandId() twice. In the printf() line, instead of calling getCommandId() again (line 60 of the code I posted) just use the return value from the previous call.

getCommandId() also needs to close the file before exiting, which I did NOT correct.

Nice one AD! :)
I did not spot that call tucked away in there.
getCommandId is being called with a string literal (constant),
which it tries to modify in strToUpper: getCommandId("move"));

The real reason you're having problems with your code is you're trying to modify a string literal:
>printf("ID: %d\n", getCommandId("move"));

You never allocated space for "move", so who knows what strtok() and your strToUpper() function are trying to do with your computer's memory.

as an aside....

the plan to "reset bit 5" as a method to convert a string to uppercase will make for some fun times if the string ever contains a numeral or other non-alphabetical character.

It is indeed rather "cute".

:)


.

This question has already been answered. Start a new discussion instead.