我試圖提取面,然后從.obj檔案中獲得各自的頂點指數,具體方法如下。我現在可以使用strtok()函式分別列印頂點指數,但是我似乎找不到正確的方法來決議它。
這里是我的代碼:
#include <stdio.h>
#include <string.h>
//lazy wavefront obj file parser。
int main(){
FILE *fp = fopen("head.obj", "r") 。
//查找檔案中的行數。
int no_lines = 0;
char ch;
while(ch != EOF){
ch = getc(fp);
if(ch == '
')
no_lines ;
}
printf("行數。%d
", no_lines)。)
//set seek point to start of the file[/span]。
fseek(fp,0,SEEK_SET)。
//獲取面孔并決議它們。
char line[100] 。
while(fgets(line, sizeof(line), fp) !=NULL){
if(line[0] == 'f'){
//split the line at spaces。
char *s = strtok(line, " ") 。
while(s != NULL){
if(*s != 'f'/span>){
/*這將列印出如下的面孔
58/35/58
59/36/59
60/37/60
我們需要得到每行的第一個數字,即58、59、60。
*/
printf("%s
", s)。)
}
s = strtok(NULL, ")。
}
}
}
fclose(fp)。
return 0;
}
輸出看起來是這樣的。
1202/1248/1202。
1220/1281/1220
1200/1246/1200。
1200/1246/1200
1220/1281/1220>
1198/1247/1198。
1201/1249/1201
1200/1246/1200
1199/1245/1199。
1201/1249/1201
1202/1248/1202
1200/1246/1200。
我想從上述輸出中提取數字,如下所示,我所需要的是每行的第一個數字。
對于下面幾行
1202/1248/1202。
1220/1281/1220
1200/1246/1200。
輸出應該是1202, 1220, 1200。
uj5u.com熱心網友回復:
簡要概述
下面的代碼決不是一個完整的Wavefront OBJ決議器,但它滿足了問題中的要求。首先,它檢查該行的第一個字符是否是'f',如果不是這種情況,那么我們可以跳過這一行。否則,就開始進行行決議。
我們首先跳過'f',然后重復兩次呼叫strtok,交替使用分隔符。在第一個中,我們讀到'/'的第一個頂點索引。在第二個中,我們讀到下一個空格字符(并忽略其結果)。指標現在是在第二個頂點索引的起點。這個程序重復進行,直到該行結束。
一些技術上的問題。
一些技術細節 根據本源,空白可以自由添加到 OBJ 檔案中,盡管本源說,"斜線前后不允許有空格"。跳過空白處本身并不困難。我的默認方法是使用這個 "狀態機 "來讀取一個單行: 手動推進一個指標并使用
'/'字符為止。這是頂點索引。sscanf讀取頂點索引是一個有效的方法。在這里嘗試使用strtok是很誘人的,然而,這使得決議更加困難,因為strtok
由于問題指出實作應該是 "簡單的",并且通常使用單個空格作為空白分隔符,所以以下的實作是可能的:
代碼
<代碼
示例輸入行。f 2/1/1 4/2/1 1/3/1.
輸出行的例子。2 4 1 .
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINE_SIZE_MAX 128U
static size_t fileToLines(FILE *fp)。
static bool parseFacesFromFile(FILE *fp)。
int main(int argc, char *argv[])。
{
if (argc != 2)
{
fprintf(stderr, "用法。%s <obj檔案名>
", argv[0])。)
exit(EXIT_FAILURE)。
}
FILE *fp = fopen(argv[1], "r"/span>)。
if (fp == NULL)
{
fprintf(stderr, "Error opening file
")。)
exit(EXIT_FAILURE)。
}
printf(" Number of lines: %zu
", fileToLines(fp))。
printf("正在決議%s
", parseFacesFromFile(fp) ? "succceeded" : "failed")。)
fclose(fp)。
}
static size_t fileToLines(FILE *fp)。
{
size_t numberOfLines = 0U;
int ch;
while ((ch = getc(fp)) != EOF)
if (ch == '
')
numberOfLines;
fseek(fp, 0L, SEEK_SET) 。
return numberOfLines。
}
static bool parseFacesFromFile(FILE *fp)
{
char line[LINE_SIZE_MAX] 。
while (fgets(line, sizeof(line), fp) != NULL)
{
if (line[0] != 'f')
continue;
char *tokenPtr;
strtok(line, " "); //讀過最初的 "f"之后
while ((tokenPtr = strtok(NULL, "/")) != NULL)
{
printf("%s", tokenPtr) 。
strtok(NULL, " "); //回傳值檢查省略,假定輸入正確。
}
putchar('
')。
}
return true;
}
額外的評論:
- 沒有使用引數的
main的典型簽名是int main(void)。 - 在問題的代碼中,
char ch在第一次使用時未被初始化。 - 函式
getc回傳一個int,它不應該被投到一個char。在后一種情況下,EOF不能被可靠地檢測到。 。
- 如果你只追求最終的結果,可以考慮使用一個OBJ加載庫并丟棄法線和紋理資料。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/314861.html
標籤:
