我正在使用fscanf
阅读文件。我想忽略非字母字符,如逗号,\,:和点。
这是我的代码:
FILE *fp;
fp = fopen(fl,"r");
char c[50];
while(fscanf(fp, "%s" ,c)!= EOF){
linkLst(c);
}
fclose(fp);
如何逐字逐句地读取非字母字符?
{ 文件的一部分如下
与答案:
1)世界上最复杂的书面语言是什么? (提示:它 使用四个字符集。)(这个问题太容易了吗?)>>日本
2)什么语言的词汇主要来自阿拉伯语(大约70%, 我被告知),但使用罗马字母? (我想知道你在哪里找到的 答案!)>>马耳他
3)什么非浪漫语言在字母N上使用波浪号(〜)? >>爱沙尼亚语 }
答案 0 :(得分:1)
您必须创建一个您读取的字符串副本,过滤掉非字母数字字符。
[Authorize, ApiExplorerSettings(IgnoreApi = true)]
public class MyController : ApiController {
public HttpResponseMessage method1() {/*...*/}
[ApiExplorerSettings(IgnoreApi = false)]
public HttpResponseMessage method2() {/*...*/}
public HttpResponseMessage method3() {/*...*/}
/*...*/
}
执行此操作后
scanf
答案 1 :(得分:0)
我将坚持“逐字逐句”阅读内容,而不是担心链接列表。
scanf
函数系列使您能够进行简单的解析,因为scanf中有足够的功能,所以不需要逐个字符地执行。如果你想用char解析字符串char,那么只需使用fgets
并执行你需要的解析。
我会坚持使用scanf,就像你正在使用的那样:
从包含以下内容的简单文件( foo.txt )开始
你好,你好吗?
并尝试扫描它:
/* NOTE: this code does NOT do what you want */
#include <stdio.h>
int main() {
char foo[128];
FILE *fp;
fp = fopen("foo.txt", "r");
do {
sscanf(input, "%[A-Za-z0-9]", foo);
fprintf(stderr, "foo: %s\n", foo);
} while(1);
return 0;
}
你得到一个无限循环打印hello
,因为scanf被卡住了,并且在“你好”之后无法隐藏空格。
所以让我们添加一个munger:
#include <stdio.h>
int main() {
char foo[128];
char mung[128];
char rv = 0;
FILE *fp;
fp = fopen("foo.txt", "r");
do {
rv = fscanf(fp, "%[A-Za-z0-9]%[^A-Za-z0-9]", foo, mung);
if(rv == EOF)
break;
fprintf(stderr, "foo: %s\n", foo);
}while(1);
}
所以munger会发布我们正在寻找的foo字符集中的所有内容(在{]中放置一个^
作为第一个字符使scanf否定内容。
这将打印出来:
foo: hello
foo: there
foo: how
foo: are
foo: you
现在,如果我们聪明,我们可以跳过mung变量的分配:
#include <stdio.h>
int main() {
char foo[128];
char rv = 0;
FILE *fp;
fp = fopen("foo.txt", "r");
do {
rv = fscanf(fp, "%[A-Za-z0-9]%*[^A-Za-z0-9]", foo);
if(rv == EOF)
break;
fprintf(stderr, "foo: %s\n", foo);
}while(1);
}
显然在我的例子中我假设foo小于128个字节。但是我们不知道,scanf(在2001年POSIX标准之后)允许你为以后必须free
的字符串动态分配内存,所以:
#include <stdio.h>
#include <stdlib.h>
int main() {
char *foo;
char rv = 0;
FILE *fp;
fp = fopen("foo.txt", "r");
do {
/* notice the & before foo, because fscanf will modify the pointer
* variable itself and assign it a new pointer after allocating
* the space for the string
*/
rv = fscanf(fp, "%m[A-Za-z0-9]%*[^A-Za-z0-9]", &foo);
if(rv == EOF)
break;
fprintf(stderr, "foo: %s\n", foo);
/* store the foo pointer somewhere for use and free it later,
* if you are sticking it in a linked list, then you should
* free it whenever you free the corrosponding node.
*
* I am just going to free it here after printing it out
*/
free(foo);
}while(1);
}
正如BLUEPIXY所指出的,这不会消耗任何以非匹配字符开头的字符。等等,
))oops helo
将陷入(null)
循环
这意味着我们需要对一个单独的操作进行修改,以便它能够解决问题:
#include <stdio.h>
#include <stdlib.h>
int main() {
char *foo;
char rv = 0;
FILE *fp;
fp = fopen("foo.txt", "r");
do {
/* notice the & before foo, because fscanf will modify the pointer
* variable itself and assign it a new pointer after allocating
* the space for the string
*/
rv = fscanf(fp, "%m[A-Za-z0-9]", &foo);
if(rv == EOF)
break;
/* foo would be null if scanf didn't read anything */
if (foo) {
fprintf(stderr, "foo: %s\n", foo);
/* store the foo pointer somewhere for use and free it later,
* if you are sticking it in a linked list, then you should
* free it whenever you free the corrosponding node.
*
* I am just going to free it here after printing it out
*/
free(foo);
}
rv = fscanf(fp, %*[^A-Za-z0-9]");
if (rv == EOF)
break;
}while(1);
}
(参见scanf(3))页面了解详情
答案 2 :(得分:-1)
使用 /// <summary>
/// Method to simulate a throw SqlException
/// </summary>
/// <param name="number">Exception number</param>
/// <param name="message">Exception message</param>
/// <returns></returns>
public static SqlException CreateSqlException(int number, string message)
{
var collectionConstructor = typeof(SqlErrorCollection)
.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, //visibility
null, //binder
new Type[0],
null);
var addMethod = typeof(SqlErrorCollection).GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Instance);
var errorCollection = (SqlErrorCollection)collectionConstructor.Invoke(null);
var errorConstructor = typeof(SqlError).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null,
new[]
{
typeof (int), typeof (byte), typeof (byte), typeof (string), typeof(string), typeof (string),
typeof (int), typeof (uint)
}, null);
var error =
errorConstructor.Invoke(new object[] { number, (byte)0, (byte)0, "server", "errMsg", "proccedure", 100, (uint)0 });
addMethod.Invoke(errorCollection, new[] { error });
var constructor = typeof(SqlException)
.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, //visibility
null, //binder
new[] { typeof(string), typeof(SqlErrorCollection), typeof(Exception), typeof(Guid) },
null); //param modifiers
return (SqlException)constructor.Invoke(new object[] { message, errorCollection, new DataException(), Guid.NewGuid() });
}
函数过滤掉每个字符。
isalpha
并且正确的函数while (fscanf(fp, "%s", c) != EOF) {
char* ptr = c;
while (*ptr) {
if (isalpha(*ptr)) {
linkLst(*ptr);
}
ptr++;
}
}
接受逐个字符而不是字符指针。
linkLst
作为参数必须linkLst
,您可以这样做:
char *
答案 3 :(得分:-1)
包含标题#include <ctype.h>
,其中包含函数isalpha(char c)
,如果true
是字母字符,则返回c
。
if ( isalpha(c))
{
// do what you wanna do
}
else
{
// ignore
}
否则,您可以使用ASCII table。像使用int
一样使用字符并进行比较。例如,要检查char
是否是字母和大写字母,您可以执行以下操作:
if ( c < 66 && c > 90)
{
// do what you wanna do
}
else
{
// ignore
}
如果c
是一个标签,那么就像这样循环:
for (int i = 0; i < sizeof(c); i++) // Then use c[i] to access to char inside it
{
if (c[i] < 66 && c[i] > 90) // or if (isalpha(c[i])
{
// do what you wanna do
}
else
{
// ignore
}
}
你也可以写:
if (c[i] < 'A' && c[i] > 'Z')
感谢ASCII表,'A' == 66
和'Z' == 90