#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
struct Book
{
int num; //图书编号
char aut[50]; //作者
float price; //图书价格
char pub[50]; //出版商
char name[50]; //书名
int kc; //库存
};
void jieshu(); //借阅
void jskc(Book b);
void jieshu()
{
struct Book b;
int s;
int w;
char sr[50];
printf("请输入要借阅的书籍(格式:《-书名-》):\n");
scanf("%s",&sr);
FILE*fp;
fp=fopen("allbook.txt","r");
fscanf(fp,"%d%s%s%s%f%d",&b.num,&b.name,&b.aut,&b.pub,&b.price,&b.kc);
if(strcmp(sr,b.name)==0&&b.kc!=0)
{
printf("是否借阅(1.YES \ 2.NO)");
scanf("%d",&s);
switch(s)
{
case 1:
jskc(b);
printf("借阅成功!\n");
break;
case 2:
ex();
}
}
else
{
printf("无法借阅!该图书可能不存在或库存不足!\n");
printf("是否需要查询?(1.yes \ 2.no)\n");
scanf("%d",&w);
switch(w)
{
case 1:
findbook();
case 2:
ex();
}
}
fclose(fp);
}
void jskc(Book b)
{
FILE*fp;
Book c[1010];
int i,j;
i = 0;
fp=fopen("allbook.txt","r");
while(fscanf(fp,"%d%s%s%s%f%d",&c[i].num,&c[i].name,&c[i].aut,&c[i].pub,&c[i].price,&c[i].kc)!=EOF)
i++;
fclose(fp);
fp = fopen("allbook.txt","w");
for(j = 0;j<i;j++)
{
if(b.num ==c[i].num&&b.name == c[i].name&&b.aut == c[i].aut&&b.pub == c[i].pub&&b.price == c[i].price&&b.kc == c[i].kc)
{
fprintf(fp,"%d %s %s %s %f %d\n",b.num,b.name,b.aut,b.pub,b.price,b.kc-1);
}
else
fprintf(fp,"%d %s %s %s %f %d\n",c[i].num,c[i].name,c[i].aut,c[i].pub,c[i].price,c[i].kc);
}
fclose(fp);
}
10 个解决方案
#1
每次基本上涉及到字符串指针的内容时,一般新手都容易有些错误(我也是)
【转】C++常识“屯”和“烫”
VC++中,在Debug模式下,会把未初始化的栈内存全部填成0xCC(204)。会把未初始化的堆内存全部填成0xCD(205)。但是Release模式下不会有这种动作,原来那块内存里是什么就是什么(Debug模式下这样干是为了让程序员知道是否被初始化)。0xCC和0xCD都超过了ASCII码0-127这个范围,因此它就被系统当成了宽字符组成的字符串,即两个字节数据组成一个字符,而0xCCCC表示的宽字符正好是“烫”字。同理,0xCDCD就是“屯”字。
这下明白了吗?(我以前也很不解)如果你在VC中选择Release模式就不会出现这种情况了(但是如果操作这个栈内存或堆内存有可能会崩溃)
如果还不明白的话可以加我QQ3300469945
【转】C++常识“屯”和“烫”
VC++中,在Debug模式下,会把未初始化的栈内存全部填成0xCC(204)。会把未初始化的堆内存全部填成0xCD(205)。但是Release模式下不会有这种动作,原来那块内存里是什么就是什么(Debug模式下这样干是为了让程序员知道是否被初始化)。0xCC和0xCD都超过了ASCII码0-127这个范围,因此它就被系统当成了宽字符组成的字符串,即两个字节数据组成一个字符,而0xCCCC表示的宽字符正好是“烫”字。同理,0xCDCD就是“屯”字。
这下明白了吗?(我以前也很不解)如果你在VC中选择Release模式就不会出现这种情况了(但是如果操作这个栈内存或堆内存有可能会崩溃)
如果还不明白的话可以加我QQ3300469945
#2
这种情况就是你的程序输出文件的时候要输出的字符串没有初始化过,但分配了内存。你自己看看哪里出了问题(注意所有字符串数组,调试一下看哪个字符串数组都是“烫”)
#3
请仔细检查scanf,fscanf,sscanf函数的返回值!
#4
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
struct Book
{
int num; //图书编号
char aut[50]; //作者
float price; //图书价格
char pub[50]; //出版商
char name[50]; //书名
int kc; //库存
};
void jieshu(); //借阅
void jskc(Book b);
void jieshu()
{
struct Book b;
int s;
int w;
char sr[50];
printf("请输入要借阅的书籍(格式:《-书名-》):\n");
scanf("%s", sr); /* remove '&' */
FILE*fp;
fp=fopen("allbook.txt","r");
fscanf(fp,"%d%s%s%s%f%d",&b.num, b.name, b.aut, b.pub, &b.price,&b.kc);
if(strcmp(sr,b.name)==0&&b.kc!=0)
{
printf("是否借阅(1.YES \ 2.NO)");
scanf("%d", &s);
switch(s)
{
case 1:
jskc(b);
printf("借阅成功!\n");
break;
case 2:
ex();
}
}
else
{
printf("无法借阅!该图书可能不存在或库存不足!\n");
printf("是否需要查询?(1.yes \ 2.no)\n");
scanf("%d",&w);
switch(w)
{
case 1:
findbook();
case 2:
ex();
}
}
fclose(fp);
}
void jskc(Book b)
{
FILE*fp;
Book c[1010];
int i,j;
i = 0;
fp=fopen("allbook.txt","r");
while(fscanf(fp,"%d%s%s%s%f%d", &c[i].num, c[i].name, c[i].aut, c[i].pub,&c[i].price,&c[i].kc)!=EOF) /* remove '&' */
i++;
fclose(fp);
fp = fopen("allbook.txt","w");
for(j = 0;j<i;j++)
{
if(b.num ==c[i].num&&b.name == c[i].name&&b.aut == c[i].aut&&b.pub == c[i].pub&&b.price == c[i].price&&b.kc == c[i].kc)
{
fprintf(fp,"%d %s %s %s %f %d\n",b.num,b.name,b.aut,b.pub,b.price,b.kc-1);
}
else
fprintf(fp,"%d %s %s %s %f %d\n",c[i].num,c[i].name,c[i].aut,c[i].pub,c[i].price,c[i].kc);
}
fclose(fp);
}
出现特殊字符,主要是字符串没有找到结束标记,注意你的输入是否导致了字符串越界。
scanf和fscanf有写输入不需要加&的,因为数组名本身就是地址。建议对比一下,那些是不需要&的。
最后,建议注意下代码风格:比如
fprintf(fp, "%d %s %s %s %f %d\n", c[i].num, c[i].name, c[i].aut, c[i].pub, c[i].price, c[i].kc);
加空格,让代码读起来更方便。
#5
任何字符串或者结构在使用之前建议初始化,
#6
在使用之前进行初始化是个良好的编程习惯。
#7
烫烫更健康!
#8
#9
#10
。。。。。。。。。。。。。。。。。。。。。。。。。
#1
每次基本上涉及到字符串指针的内容时,一般新手都容易有些错误(我也是)
【转】C++常识“屯”和“烫”
VC++中,在Debug模式下,会把未初始化的栈内存全部填成0xCC(204)。会把未初始化的堆内存全部填成0xCD(205)。但是Release模式下不会有这种动作,原来那块内存里是什么就是什么(Debug模式下这样干是为了让程序员知道是否被初始化)。0xCC和0xCD都超过了ASCII码0-127这个范围,因此它就被系统当成了宽字符组成的字符串,即两个字节数据组成一个字符,而0xCCCC表示的宽字符正好是“烫”字。同理,0xCDCD就是“屯”字。
这下明白了吗?(我以前也很不解)如果你在VC中选择Release模式就不会出现这种情况了(但是如果操作这个栈内存或堆内存有可能会崩溃)
如果还不明白的话可以加我QQ3300469945
【转】C++常识“屯”和“烫”
VC++中,在Debug模式下,会把未初始化的栈内存全部填成0xCC(204)。会把未初始化的堆内存全部填成0xCD(205)。但是Release模式下不会有这种动作,原来那块内存里是什么就是什么(Debug模式下这样干是为了让程序员知道是否被初始化)。0xCC和0xCD都超过了ASCII码0-127这个范围,因此它就被系统当成了宽字符组成的字符串,即两个字节数据组成一个字符,而0xCCCC表示的宽字符正好是“烫”字。同理,0xCDCD就是“屯”字。
这下明白了吗?(我以前也很不解)如果你在VC中选择Release模式就不会出现这种情况了(但是如果操作这个栈内存或堆内存有可能会崩溃)
如果还不明白的话可以加我QQ3300469945
#2
这种情况就是你的程序输出文件的时候要输出的字符串没有初始化过,但分配了内存。你自己看看哪里出了问题(注意所有字符串数组,调试一下看哪个字符串数组都是“烫”)
#3
请仔细检查scanf,fscanf,sscanf函数的返回值!
#4
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
struct Book
{
int num; //图书编号
char aut[50]; //作者
float price; //图书价格
char pub[50]; //出版商
char name[50]; //书名
int kc; //库存
};
void jieshu(); //借阅
void jskc(Book b);
void jieshu()
{
struct Book b;
int s;
int w;
char sr[50];
printf("请输入要借阅的书籍(格式:《-书名-》):\n");
scanf("%s", sr); /* remove '&' */
FILE*fp;
fp=fopen("allbook.txt","r");
fscanf(fp,"%d%s%s%s%f%d",&b.num, b.name, b.aut, b.pub, &b.price,&b.kc);
if(strcmp(sr,b.name)==0&&b.kc!=0)
{
printf("是否借阅(1.YES \ 2.NO)");
scanf("%d", &s);
switch(s)
{
case 1:
jskc(b);
printf("借阅成功!\n");
break;
case 2:
ex();
}
}
else
{
printf("无法借阅!该图书可能不存在或库存不足!\n");
printf("是否需要查询?(1.yes \ 2.no)\n");
scanf("%d",&w);
switch(w)
{
case 1:
findbook();
case 2:
ex();
}
}
fclose(fp);
}
void jskc(Book b)
{
FILE*fp;
Book c[1010];
int i,j;
i = 0;
fp=fopen("allbook.txt","r");
while(fscanf(fp,"%d%s%s%s%f%d", &c[i].num, c[i].name, c[i].aut, c[i].pub,&c[i].price,&c[i].kc)!=EOF) /* remove '&' */
i++;
fclose(fp);
fp = fopen("allbook.txt","w");
for(j = 0;j<i;j++)
{
if(b.num ==c[i].num&&b.name == c[i].name&&b.aut == c[i].aut&&b.pub == c[i].pub&&b.price == c[i].price&&b.kc == c[i].kc)
{
fprintf(fp,"%d %s %s %s %f %d\n",b.num,b.name,b.aut,b.pub,b.price,b.kc-1);
}
else
fprintf(fp,"%d %s %s %s %f %d\n",c[i].num,c[i].name,c[i].aut,c[i].pub,c[i].price,c[i].kc);
}
fclose(fp);
}
出现特殊字符,主要是字符串没有找到结束标记,注意你的输入是否导致了字符串越界。
scanf和fscanf有写输入不需要加&的,因为数组名本身就是地址。建议对比一下,那些是不需要&的。
最后,建议注意下代码风格:比如
fprintf(fp, "%d %s %s %s %f %d\n", c[i].num, c[i].name, c[i].aut, c[i].pub, c[i].price, c[i].kc);
加空格,让代码读起来更方便。
#5
任何字符串或者结构在使用之前建议初始化,
#6
在使用之前进行初始化是个良好的编程习惯。
#7
烫烫更健康!
#8
#9
#10
。。。。。。。。。。。。。。。。。。。。。。。。。