我希望名称在justify-content: center;
之前保留所有字符。
'\0'
我可以这样做:
#include <stdio.h>
int main(){
char line[] = "1999-08-01,14.547,0.191,United Kingdom";
unsigned int year, month, day;
float temp, uncertainty;
char name[100];
sscanf(line, "%u - %u - %u, %f , %f , %s", &year, &month,
&day, &temp, &uncertainty, name);
printf("%u-%u-%u,%lf,%lf,%s\n", year, month, day, temp, uncertainty, name);
}
但我发现这非常不优雅。
答案 0 :(得分:3)
sscanf
不是最优雅的界面,但它有很多功能。其中之一是能够找出你在输入字符串中的位置,这可以让你提取(或只是指向)“输入的其余部分”。
例如,之后;
int nchar = -1;
int nfield = sscanf(line, "%u - %u - %u, %f , %f , %n", &year, &month,
&day, &temp, &uncertainty, &nchar);
nchar
将包含名称字段line
中的偏移量(除非它仍为-1,表示sscanf
与格式字符串不匹配)。如果该字段延伸到line
的末尾,则可以直接使用它(line + nchar
)或在检查它不是太长后将其复制到不同的字符串中。
如果line
与其名称相反,包含多行,并且您希望将字符串提取到换行符,则可以使用两种%n
格式,其间为%*[^\n]
(这位明星压制副本,以避免出现超限问题):
char name[NAME_MAX + 1];
int nstart = -1, nend = -1;
int nfield = sscanf(line, "%u - %u - %u, %f , %f , %n%*[^\n]%n", &year, &month,
&day, &temp, &uncertainty, &nstart, &nend);
if (nend > 0) {
if (nend - nstart <= NAME_MAX) {
memcpy(name, line + nstart, nend - nstart);
name[nend - nstart] = 0;
}
else {
/* name is too long */
}
}
else if (nstart > 0) {
/* Name was 0 bytes long. Sscanf requires that %[ match at least
* one character; if not, it fails the scan.
*/
name[0] = 0; /* Perhaps you wanted to signal an error
}
else {
/* Line didn't match format */
}
显然,我可以避免使用固定长度的缓冲区,并且当我知道它有多大时,需要通过动态分配缓冲区来检查溢出:
char* name = NULL;
// ...
if (nend > 0)
name = strndup(line + nstart, nend - nstart);
// or, if you don't like strndup
// name = malloc(nend - nstart + 1);
// memcpy(name, line + nstart);
// name[nend - nstart] = 0;
如果你真正想要的是一个动态分配的字符串并且你有一个符合Posix的sscanf
,你可以通过使用m
长度修饰符来避免这种麻烦,这是一个全面的最简单的解决方案
char* name = NULL;
int nfield = sscanf(line, "%u - %u - %u, %f , %f , %m[^\n]", &year, &month,
&day, &temp, &uncertainty, &name);
有关详细信息,请参阅您的sscanf
联机帮助页。在name
被动态分配的所有情况下,不要忘记在完成它时释放()它。
答案 1 :(得分:2)
这应该有效:
char line[] = "1999-08-01,14.547,0.191,United Kingdom";
unsigned int year, month, day;
float temp, uncertainty;
char name[100];
sscanf(line, "%u - %u - %u, %f , %f , %99[^\n]", &year, &month,
&day, &temp, &uncertainty, name);
printf("%u-%u-%u,%lf,%lf,%s\n", year, month, day, temp, uncertainty, name);
找不到 '\n'
,但由于无法达到99的限制,sscanf
将继续读取,直到字符串结束标记。
答案 2 :(得分:0)
几天前,我正在阅读书中的第2章&#34; Unix系统编程:通信,并发,线程&#34; ,2003年版本,我研究了一个例子,它导致使用自定义分隔符将字符串分解为标记(它可以是,或_或空格或其他)。它使用了strtok()C库函数。以下是调整示例以满足您的需求。我将提供2个文件:
makeargv.c
private View mView;
private EditText editText;
@Override
public View onCreateView(LayoutInflater layoutInflater, ViewGroup container, Bundle savedInstanceState) {
if (mView != null) {
ViewGroup group = (ViewGroup) mView.getParent();
if (group != null) {
group.removeView(mView);
}
} else {
//Inflate layout for this fragment
mView = layoutInflater.inflate(R.layout.frgament_layout, container, false);
edittext = (TextView)(mView.findViewById(R.id.textViewVol));
editText.setText("% Volumne");
return mView;
}
main.c
#include <errno.h>
#include <stdlib.h>
#include <string.h>
/* frees all the memory that was allocated by makeargv */
void freemakeargv(char **argv)
{
if (argv == NULL)
return;
if (*argv != NULL)
free(*argv);
free(argv);
}
/* Now the function that breaks string s into tokens */
int makeargv(const char *s, const char *delimiters, char ***argvp)
{
int error; int i;
int numtokens;
const char *snew;
char *t;
if ((s == NULL) || (delimiters == NULL) || (argvp == NULL))
{ errno = EINVAL; return -1; }
*argvp = NULL; /* so that a failed call to malloc,will leave it NULL */
/* now we consume any initial delimiters characters of input s */
snew = s + strspn(s, delimiters); /* snew is real start of string */
if ((t = malloc(strlen(snew) + 1)) == NULL)
return -1;
strcpy(t, snew);
numtokens = 0;
if (strtok(t, delimiters) != NULL) /* count number of tokens in s */
for (numtokens = 1; strtok(NULL, delimiters) != NULL; numtokens++) ;
/* next,create argument array for ptrs to the tokens */
if ((*argvp = malloc((numtokens + 1)*sizeof(char *))) == NULL)
{
error = errno;
free(t);
errno = error;
return -1;
}
/* now insert pointers-to-tokens into the argument array */
if (numtokens == 0) free(t);
else
{
strcpy(t, snew);
**argvp = strtok(t, delimiters);
for (i = 1; i < numtokens; i++)
*((*argvp) + i) = strtok(NULL, delimiters);
}
*((*argvp) + numtokens) = NULL; /* append final NULL pointer */
return numtokens;
}
gcc -Wall -std = c99 -o tokenizer main.c makeargv.c
并运行它
./ tokenizer
答案 3 :(得分:0)
@rici的好方法的变化:
如何让sscanf读到&#39; \ 0&#39;字符
使用>>> df
a b c
0 0 1 2
1 3 4 5
2 6 7 8
3 9 10 11
4 12 13 14
5 15 16 17
>>> df1
a b c
0 0 1 2
1 3 4 5
2 6 7 8
>>> df.loc[0, 'a'] = 99
>>> df
a b c
0 99 1 2
1 3 4 5
2 6 7 8
3 9 10 11
4 12 13 14
5 15 16 17
>>> df1
a b c
0 99 1 2
1 3 4 5
2 6 7 8
来处理&#34;线路的其余部分&#34;
"%n"
将扫描的偏移量记录到该点,如果它到达那么远
"%n"
会进行扫描,但不会将所有角色保存到每个OP的%*[^\n]
并保留在第34行
用它来分配结束字符串。
'\n'